Angular2子组件作为数据

pbz*_*pbz 12 angular

假设我有两个组成部分:parentchild.HTML将如下所示:

<parent title="Welcome">
    <child name="Chris">Blue Team</child>
    <child name="Tom">Red Team</child>
</parent>
Run Code Online (Sandbox Code Playgroud)

最终输出如下:

<h1>Welcome</h2>
<ul>
    <li><b>Chris</b> is on the Blue Team</li>
    <li><b>Tom</b> is on the Red Team</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

父组件:

@Component({
  selector: 'parent',
  directives: [ChildComponent], // needed?
  template: `
    <h1>{{title}}</h1>
    <ul>
       <li *ngFor="#child of children()">{{child.content}}<li>
    </ul>`
})
export class ParentComponent {

    @Input() title;

    children() {
        // how?
    }

}
Run Code Online (Sandbox Code Playgroud)

如何从父级中访问子组件并获取其内容?

此外,我不希望自动渲染孩子.根据某些条件,我可能会选择不显示某些孩子.

谢谢.

Gün*_*uer 12

<ng-content>

要将内容投影到元素(包含),您需要使用<ng-content>类似的元素

@Component({
  selector: 'parent',
  directives: [ChildComponent], // needed?
  template: `
    <h1>{{title}}</h1>
    <ul>
       <li *ngFor="letchild of children()">
         <ng-content></ng-content>
       </li>
    </ul>`
})
Run Code Online (Sandbox Code Playgroud)

<ng-content select="xxx">

但这不适用于您的用例,因为<ng-content>它不会生成内容,它只会对其进行投影(作为一个放置在组件模板中显示子项的放置器).

即使*ngFor会生成3个<ng-content>元素,子元素也只会在第一个<ng-content>元素中显示一次.

<ng-content> 允许使用选择器

<ng-content select="[name=Chris]"></ng-content>
Run Code Online (Sandbox Code Playgroud)

模板之类的地方

<ul>
   <li>
     <ng-content select="[name=Chris]"></ng-content>
   </li>
</ul>`
Run Code Online (Sandbox Code Playgroud)

会导致

<h1>Welcome</h2>
<ul>
    <li><b>Chris</b> is on the Blue Team</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

在Angular 2中使用ngForTemplate时,Binding事件中解释了一种更灵活,更强大的方法(来自@kemsky的评论)

<template>,@ViewChildren()*ngForTemplate

如果你包裹孩子<template>的标签,你可以使用访问它们@ContentChildren(),并使用它们插入*ngFor*ngForTemplate.

我在这里使用内部的一点点黑客*ngFor.有一种更好的方法正在进行中(ngTemplateOutlet https://github.com/angular/angular/pull/8021已经合并)

@Component({
  selector: 'parent',
  template: `
    <h1>{{title}}</h1>
    <ul>
      <li *ngFor="let child of templates">
         <!-- with [child] we make the single element work with 
              *ngFor because it only works with arrays -->
         <span *ngFor="let t of [child]" *ngForTemplate="child"></span>
      </li>
    </ul>
    <div>children:{{children}}</div>
    <div>templates:{{templates}}</div>
    `
})
export class ParentComponent {

  @Input() title;
  @ContentChildren(TemplateRef) templates;
}

@Component({
    selector: 'my-app',
    directives: [ParentComponent],
    template: `
    <h1>Hello</h1>
<parent title="Welcome">
  <template><child name="Chris">Blue Team</child></template>
  <template><child name="Tom">Red Team</child></template>
</parent>    
    `,
})
export class AppComponent {}
Run Code Online (Sandbox Code Playgroud)

Plunker的例子

另请参见如何在没有ngFor的情况下多次重复HTML片段,如果没有其他@Component,则ngTemplateOutlet可以获得更多Plunker示例.

更新Angular 5

ngOutletContext 被重命名为 ngTemplateOutletContext

另见https://github.com/angular/angular/blob/master/CHANGELOG.md#500-beta5-2017-08-29