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

Angular: display content projection with nested children

我有一个组件,我想在其中的子组件中显示可配置 html。客户端无法访问子组件。所以我想我要找的是 content projection

<Parent>
 <ng-template #editTemplate> //custom 
   <button>Edit Me </button>
 </ng-template>    
 <child1>
     ...
     <child4>
       I would like to show the #editTemplate here
     </child4>
 </child1>
</Parent>

所以在child4

里面

我有这个HTML

<div>
  <ng-content #editTemplate></ng-content>
</div>

但是我无法显示按钮。我在这里做错了什么?

这里是内容投影和依赖注入的有趣组合。

<ng-template #editTemplate> 正在 content-projected 进入 Parent 组件

<Parent>
 <ng-template #editTemplate> <--- projected into <Parent>
   <button>Edit Me </button>
 </ng-template>
</Parent>

所以 Parent 通过 Content Child 直接引用它,如果你的 Parent 组件看起来像这样:

@Component({
  selector: 'parent',
  template: `
  <h2>Parent here!</h2>

  <ng-content></ng-content> <--- #editTemplate will get projected here

  <child1></child1>
  `,
  styles: [`h1 { font-family: Lato; }`],
})
export class ParentComponent {
  @ContentChild('editTemplate') editTemplate: TemplateRef<any>; // <--- reference to #editTemplate
}

但是,child4嵌套了好几层,所以依赖注入是你的朋友,否则你需要在每一层中配置一个引用来完成从 Parent 向下链接到 child4.

不过,使用 DI,您可以将 Parent 组件直接注入 child4,然后他可以访问 Parent 组件实例上的 editTemplate 引用并使用*ngTemplateOutlet 插入来自 TemplateRef 的视图。

所以 child4 可能看起来像这样:

@Component({
  selector: 'child4',
  template: `
  <h3>Child 4 here!</h3>
  <div>And here's the injected template:</div>

  <ng-container *ngTemplateOutlet="projectedTemplate"></ng-container> <--- use *ngTemplateOutlet to render editTemplate
  `,
  styles: [`h1 { font-family: Lato; }`],
})
export class Child4Component {
  projectedTemplate: TemplateRef<any>;

  constructor(private parentComponent: ParentComponent) {} // <-- inject ParentComponent instance

  ngOnInit() {
    this.projectedTemplate = this.parentComponent.editTemplate; // <-- set *ngTemplateOutlet to editTemplate
  }
}

Here's a StackBlitz 展示了这种方法。