如何将模板传递到Angular中的嵌套组件



我正在NativeScript和Angular中构建自动完成(这个问题对纯Angular也有效(。

标记如下:

<StackLayout>
<TextField #keywords [hint]="options?.hint" [(ngModel)]="occupation"
(textChange)="keywordsInputChange$.next(keywords.text)">
</TextField>
<ng-container *ngTemplateOutlet="parentTemplate"></ng-container>
<ScrollView orientation="vertical" height="200" *ngIf="dataItems?.length > 0" class="m-r-16 m-l-16 search-view">
<ListView [items]="dataItems" (itemTap)="onItemTap($event)">
<ng-template let-item="item">
...
</ng-template>
</ListView>
</ScrollView>

它将从外部使用:

<px-lookup (selected)="onOccupationSelected($event)" [options]="occupationLookupOptions">
<ng-template let-item>
<StackLayout class="search-item" backgroundColor="red">
<Label [text]="item.text"></Label>
</StackLayout>
</ng-template>
</px-lookup>

如您所见,我想将自定义模板传递给我的查找,ListView将使用该模板。我正在检索像这个一样的模板

@ContentChild(TemplateRef, { static: false }) parentTemplate: TemplateRef<any>;

我可以通过定义在查找中呈现它而没有任何问题

<ng-container *ngTemplateOutlet="parentTemplate; context: { $implicit: item }"></ng-container>

然而,当我试图将它放在LietView中时,它也需要模板,我无法使其工作。我正在处理类似'的错误:在列表模板中找不到合适的视图!嵌套级别:0'任一项都被渲染为[Object-Object]

我尝试过这些选项:

<ListView [items]="dataItems" (itemTap)="onItemTap($event)">
1. Option ===> <ng-container *ngTemplateOutlet="parentTemplate"></ng-container> -->
2. Option ===><ng-content></ng-content>
3. Option ===> <ng-template let-item="item"> (top template that is required by ListView)
<ng-container *ngTemplateOutlet="parentTemplate; context: { $implicit: item }"></ng-container> (Tried to render another template with current one by passing item down the pipe)
</ng-template>
</ListView>

有人知道我怎样才能做到这一点吗?

感谢

关键是通过利用TemplateRef的依赖项注入,创建一个用于存储模板引用的指令。

首先是指令:

// my-template.directive.ts
@Directive({ selector: '[myTemplate]' })
export class MyTemplateDirective  {
@Input('myTemplate') type: string;
constructor(public template: TemplateRef<any>) {}
}

(请注意,尽管在这种简单的情况下没有使用type属性,但对于多个嵌套模板,这是必要的(

之后,在自动完成组件中,您将查找具有该指令的内容子级,如下所示:

// autocomplete.component.ts
@ContentChild(MyTemplateDirective, { static: false }) set setTemplate(value: MyTemplateDirective) {
// for multiple templates you could implement logic using value.type
// for example:
// this.parentTemplates[value.type] = value.template
this.parentTemplate = value.template;
};

并且在模板中

// autocomplete.component.html
// Basically your Option 3
<ListView [items]="dataItems" (itemTap)="onItemTap($event)">   
<ng-template let-item="item">
<ng-container *ngTemplateOutlet="parentTemplate; context: { $implicit: item }"></ng-container>
</ng-template>
</ListView>

那么你会这样使用它:

<px-lookup (selected)="onOccupationSelected($event)" [options]="occupationLookupOptions">
<ng-template let-item myTemplate="pxLookupElem">
<StackLayout class="search-item" backgroundColor="red">
<Label [text]="item.text"></Label>
</StackLayout>
</ng-template>
</px-lookup>

最新更新