首页 > 解决方案 > 从 QueryList 中识别特定的 Angular TemplateRef

问题描述

在 Angular 6/7 中,我有一个组件,我将内容投影到其中(ParentComponent模板):

<my-component [templateNames]="['t1', 't2']">
  <ng-template name="t1">...</ng-template>
  <ng-template name="t2">...</ng-template>
  <ng-template>...</ng-template> <!-- not included in [templateNames] -->
</my-component>

MyComponent课堂上,我可以使用ContentChildren装饰器获取所有模板的QueryList

@ContentChildren(TemplateRef) templates: QueryList<TemplateRef<any>>;

挑战在于我想在特定模板上执行代码,这些模板由ParentComponent通过@Input() templateNames.

processTemplates() {
  for (const name of this.templateNames) {
    const templateRef = this.getTemplateByName(name);
    this.doWork(templateRef);
  }
}

getTemplateByName(name) {
  const templates = this.templates.toArray();

  return templates.find(t => ?); // what can I query to distinguish templates?
}

问题是我不知道如何读取name属性或我在ParentComponent的ng-template标签上设置的任何其他内容。我不知道如何区分一个 TemplateRef 和另一个;

请记住,MyComponent不能对将使用什么名称或是否应该处理所有ng-templates做出任何假设——我上面示例中的最后一个不应该被处理,因为它没有在@Input() templateNames中列出。我可以在ParentComponent中设置什么来帮助我区分两个TemplateRef吗?

标签: angularangular-templateangular-template-variable

解决方案


您可以使用名称输入参数创建指令:

@Directive({
  selector: '[template-name]'
})
export class TableColumnDirective {

  constructor(public readonly template: TemplateRef<any>) { }

  @Input('template-name') columnName: string;
}

使用这种方式:

  <my-component>
      <ng-template template-name="t1">...</ng-template>
      <ng-template template-name="t2">...</ng-template>
      ...

然后以my-component这种方式注入:

@ContentChildren(TableColumnDirective) templates: QueryList<TableColumnDirective>;

有关更详细的解释/示例,请查看此问题的已接受答案


推荐阅读