ngForTemplate - 通过ContentChild使用模板,或者回退到默认

时间:2017-05-04 15:11:34

标签: angular ngfor

使用Angular 4.0.3

我正在尝试创建一个组件来将数组显示为列表。我需要选择将模板传递给此组件。如果传递了模板,则将使用它呈现列表。否则,应使用嵌入模板进行渲染。

我发现了一个部分解决了我正在尝试做的事情的Plunkr - 它展示了如何将模板传递给组件,并让组件使用它进行渲染。可在此处找到:https://embed.plnkr.co/ollxzUhka77wIXrJGA9t/

我已经分叉并尝试添加所需的默认模板功能。要做到这一点,我已经:

  • src/app.ts

    • 添加了dynamic-list组件的实例,没有模板(第29-30行)
  • src/dynamic-list.component.ts

    • 添加了后备模板(第5-7行)
    • 修改ngForTemplate引用以使用itemTemplate(如果存在),否则回退到defaultItemTemplate(第4行)
    • 使用defaultItemTemplate创建@ViewChild(TemplateRef)以获取对嵌入式默认模板的引用

可以在https://embed.plnkr.co/QtMk3h/

找到那个plunkr

运行时,我遇到了这个例外:

  

./DynamicListComponent类中的错误DynamicListComponent - 内联模板:0:29

我不确定我做错了什么,因为设置*ngForTemplate="itemTemplate"有效,但*ngForTemplate="defaultItemTemplate"*ngForTemplate="itemTemplate || defaultItemTemplate"都没有。

我做错了什么?

我也注意到*ngFor已被弃用,所以也许我现在正以错误的方式接近这个?

1 个答案:

答案 0 :(得分:2)

我使用Angular4 +添加了else子句重写了这个plnkr。

https://plnkr.co/edit/i3czMfuziB9eWkiepEW0?p=preview

  @Component({
    selector: 'dynamic-list',
    template: `<div *ngFor="let item of items">
         <ng-container *ngIf="itemTemplate;else elseBlock">
            <ng-container *ngTemplateOutlet="itemTemplate; context: {\$implicit:item}"></ng-container>
         </ng-container>
    </div>

    <ng-template #elseBlock>else</ng-template>
    `
  })
  export class DynamicListComponent {

    @ContentChild(TemplateRef)
    public itemTemplate: TemplateRef;

    @Input()
    public items: number[];

    ngAfterContentInit() {
      console.log(this.itemTemplate);
    }
  }


  @Component({
    selector: 'dynamic-list-item',
    template: `<div>
          Template Item #:{{item}}
  </div>`
  })
  export class DynamicListItemTemplateComponent {
    @Input() public item: number;
  }

  @Component({
    selector: 'my-app',
    providers: [],
    template:`
  <h3>Inline</h3>

  <h3>Default</h3>
  <dynamic-list [items]="items">
  </dynamic-list>

  <h3>Not Default</h3>
  <div  *ngFor="let item of items">
    <div>
    Inline template item #: {{item}}
    </div>
  </div>


  <h3>List component with inline template</h3>
  <dynamic-list [items]="items">
    <ng-template let-item>
        Inline template item #: {{item}}
    </ng-template>
  </dynamic-list> 


  <h3>List component with component template</h3>
  <dynamic-list [items]="items">
    <dynamic-list-item template="let item" [item]="item"></dynamic-list-item>
  </dynamic-list> 

    `,
  })
  export class App {
    private items = [1, 2, 3, 4];
  }