我正在尝试构建一个多选择组件,该组件可以为每个选择选项元素采用一个模板。大部分情况下,模板是从选项组件中的ng-content抓取的,并在“选择弹出窗口”中显示。
尝试在选择组件中显示所选选项时遇到问题。似乎模板一次只能显示在一个位置,因此当所选选项显示在选择项中时,该模板将从弹出窗口中删除。
有什么办法可以克隆TemplateRef组件?我实际上不介意是否不会针对模板更新上下文,因为我当前不使用模板中的任何内容,而是模板。
为了清晰起见,在下面包括一些代码片段,我认为还可以。
在somepage.component.html
中的用法:
<my-select [(value)]="vals">
<my-option *ngFor="let x of [1,2,3]" [value]="x">Option {{x}}</my-option>
</my-select>`
my-select.component.html
...
<ng-container [ngTemplateOutlet]="getSelectedOptionTemplate()"></ng-container>
...
my-select.component.ts
getSelectedOptionTemplate(){
// Some way to clone here could solve the issue?
return this.getSelectedOption().template;
}
my-select-overlay.component.html
...
<ng-container *ngFor="let opt of options;">
<ng-container [ngTemplateOutlet]="getTemplate(opt)"></ng-container>
</ng-container>
...
my-option.component.html
<ng-template>
<ng-content></ng-content>
</ng-template>
my-option.component.ts
...
@ViewChild(TemplateRef)
template: TemplateRef<any>;
...
答案 0 :(得分:0)
我在 Github 上找到了解决此问题的方法。
当 TemplateRef
包装包含 ng-template
的组件时,使用相同的 ng-content
似乎有效。
想象一下,我们需要获得类似的东西:
<ng-template>
<my-option>
... option content ...(<ng-content></ng-content>)
</my-option>
</ng-template>`
为了获得上面的结构,我们可以实现一个structural directive。来自文档:
<块引用>Angular 对结构指令前的星号进行变换
进入一个围绕宿主元素的 <ng-template>
和它的
后代。
结构指令的代码是:
@Directive({
selector: "[appOptionTemplate]"
})
export class OptionTemplateDirective {
@Input("appOptionTemplate")
value: any;
constructor(
public templateRef: TemplateRef<any>
) {}
}
(注意以下几点:
templateRef
Input
属性)在填充选择选项时,我们将使用以下内容:
<app-select>
<ng-container *ngFor="let x of [1,2,3]; let i=index;">
<app-option *appOptionTemplate="x">
Option {{x}}
</app-option>
</ng-container>
</app-select>
现在,我们将使用结构指令来查询 select
组件中的内容:
@ContentChildren(OptionTemplateDirective)
options: QueryList<OptionTemplateDirective>;
为了显示选项,我们将使用:
<ng-container *ngTemplateOutlet="option.templateRef"></ng-container>
示例: https://stackblitz.com/edit/angular-ivy-pues8t
Github 主题:
https://github.com/angular/angular/issues/37995
有关结构指令的更多信息: