Angular2 child component as data

前端 未结 1 1561
渐次进展
渐次进展 2020-11-28 11:24

Let\'s say I have two components: parent and child. The HTML would look like this:


    

        
相关标签:
1条回答
  • 2020-11-28 12:11

    <ng-content>

    For projecting content to an element (transclusion) you would need the <ng-content> element like

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

    but that won't work for your use case because <ng-content> doesn't produce content, it only projects it (works as a placehoder where children are displayed within your components template.

    Even though *ngFor would produce 3 <ng-content> elements, the children would only be displayed once in the first <ng-content> element.

    <ng-content> allows to use selectors like

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

    where a template like

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

    would result in

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

    A more flexible and powerful approach explained in Binding events when using a ngForTemplate in Angular 2 (from @kemsky s comment)

    <template>, @ViewChildren(), and *ngForTemplate

    If you wrap the children in <template> tags you can access them using @ContentChildren() and insert them using *ngFor and *ngForTemplate.

    I am using a little hack here with the inner *ngFor. There is a better approach work in progress (ngTemplateOutlet https://github.com/angular/angular/pull/8021 already merged)

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

    See also How to repeat a piece of HTML multiple times without ngFor and without another @Component for more ngTemplateOutlet Plunker examples.

    update Angular 5

    ngOutletContext was renamed to ngTemplateOutletContext

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

    0 讨论(0)
提交回复
热议问题