繁体   English   中英

Angular 带有嵌套子项的内容投影

[英]Angular Content projection with nested children

StackBlitz 示例在这里

我有一个组件,我希望用户在其中定义自己的模板,然后我想将该模板传递给一些嵌套的子级。 我在获取父组件中的模板实例时遇到问题。

我有我的指令在这里

@Directive({
  selector: '[customTemplate]',
})
export class CustomTemplate {
  public field!: string;

  constructor(public el: ElementRef) {}
}

我想把它放在一个父对象中并获取这些指令的所有实例。

<div customTemplate field="test1">
  <ng-template myTemplate>
    <P>Some text here T1</P>
  </ng-template>
</div>
<div customTemplate field="test2">
  <ng-template myTemplate>
    <P>Some text here T2</P>
  </ng-template>
</div>

<Child1>
  <Child2>I'm going to render the ng-templates of myTemplate here</Child2>
</Child1>

在我的父组件中,我有这个

    @Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements AfterViewInit {
  @ContentChildren(CustomTemplate)
  public templates?: QueryList<CustomTemplate>;

  ngAfterViewInit(): void {
    console.log(this.templates);
    //here how do I get the instances of CustomTemplate
    
  }
}

查询列表为空在此处输入图像描述

我相信满足的孩子可能不是正确的选择。 使用ViewChildren会导致他们被发现。 但是,需要进行一些修改。

您的指令中的selector设置为[customTemplate] 这很好,但是选择器区分大小写。 因此,在您的 HTML 中,当您将其用作CustomTemplate时,它不会被发现。 因此,将您的 HTML 更改为 customTemplate 或更新您的选择器以具有大写字母 C。

其次,为了对所说的 ViewChildren 做任何有价值的事情,正如这里提到的( @ViewChildren Querylist Array 在使用 *ngFor 呈现子级时为空),您需要subscribe AfterViewInit中发生的任何更改

前任:

this.templates.changes.subscribe((x) => console.log("From Change Sub: ", x));

最后,不要尝试使用字符串文字来查找孩子,而是传递实际的 class 名称,如下所示:

@ViewChildren(CustomTemplate)而不是@ViewChildren('CustomTemplate')@ViewChildren('customTemplate')

后两个不起作用,第一个起作用。 如果您确实决定更改 class 的名称,那么第一个也将在整个应用程序中传播,并且在没有类型检查器的任何地方都会找到它。

更新了 stackblitz https://stackblitz.com/edit/angular-z5a8ae?file=src/app/app.component.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM