角度一次在多个位置使用同一TemplateRef-克隆TemplateRef吗?

时间:2018-10-30 13:02:30

标签: angular angular6

我正在尝试构建一个多选择组件,该组件可以为每个选择选项元素采用一个模板。大部分情况下,模板是从选项组件中的ng-content抓取的,并在“选择弹出窗口”中显示。

Options display fine

尝试在选择组件中显示所选选项时遇到问题。似乎模板一次只能显示在一个位置,因此当所选选项显示在选择项中时,该模板将从弹出窗口中删除。

Options display wrong

有什么办法可以克隆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>;
...

1 个答案:

答案 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


有关结构指令的更多信息:

https://angular.io/guide/structural-directives