问题 Angular2子组件作为数据


假设我有两个组成部分: parent 和 child。 HTML将如下所示:

<parent title="Welcome">
    <child name="Chris">Blue Team</child>
    <child name="Tom">Red Team</child>
</parent>

最终输出如下:

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

父组件:

@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?
    }

}

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

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

谢谢。


10211
2018-04-20 21:49


起源

有可能实现这一点,但这只是太多的工作,你可以得到非常接近的例子 这里 - kemsky


答案:


<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>`
})

<ng-content select="xxx">

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

即使 *ngFor 会产生3 <ng-content> 这些元素只会在第一个元素中显示一次 <ng-content> 元件。

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

<ng-content select="[name=Chris]"></ng-content>

模板之类的地方

<ul>
   <li>
     <ng-content select="[name=Chris]"></ng-content>
   </li>
</ul>`

会导致

<h1>Welcome</h2>
<ul>
    <li><b>Chris</b> is on the Blue Team</li>
</ul>

一种更加灵活和强大的方法解释了 在Angular 2中使用ngForTemplate时绑定事件 (来自@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 {}

Plunker的例子

也可以看看 如何在没有ngFor且没有其他@Component的情况下多次重复一段HTML 更多 ngTemplateOutlet Plunker的例子。

更新Angular 5

ngOutletContext 被重命名为 ngTemplateOutletContext

也可以看看 https://github.com/angular/angular/blob/master/CHANGELOG.md#500-beta5-2017-08-29


12
2018-04-21 04:58





也许你正在寻找这个? https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-local-var

您可以将本地var分配给父视图中的任何子项

<child #child1></child>
<child #child2></child>
<button (click)="child1.doSomething()">Trigger child1</button>

-3
2018-04-21 00:33