组件使用内联模板进行转换

J.P*_*rge 7 angular2-components angular

我正在使用Angular 2-rc3并且Component我想要以一种不同的方式应用转换.这是我的组件:

import { Component, Input } from '@angular/core';

@Component({
    selector: 'my-list',
    template: `<ul>
        <li *ngFor="let item of data">
            -- insert template here --
            <ng-content></ng-content>
        </li>
    </ul>`
})
export class MyListComponent {
    @Input() data: any[];
}
Run Code Online (Sandbox Code Playgroud)

我这样使用它:

<my-list [data]="cars">
    <div>{{item.make | uppercase}}</div>
</my-list>
Run Code Online (Sandbox Code Playgroud)

如您所见,我正在尝试定义将由我的组件使用的内联模板.现在这非常错误.首先,一个数据绑定异常说出来can't read property 'make' of undefined.它试图读取item.make我周围的组件,而不是MyListComponent.但即使我暂时禁用此功能:

<my-list [data]="cars">
    <div>{item.make | uppercase}</div>
</my-list>
Run Code Online (Sandbox Code Playgroud)

然后出现第二个问题:

-- insert template here --
-- insert template here --
-- insert template here --
-- insert template here --
{item.make | uppercase}
Run Code Online (Sandbox Code Playgroud)

因此Angular实际上并不复制模板以供在其中使用*ngFor,它只是绑定元素,它们最终与最后一项相关联.

我如何让它工作?

我和AngularJS有同样的问题,petebacondarwin发布了一个通过编译操作DOM的解决方案,这很棒.通过注入ElementRef我的组件,我有Angular 2的这个选项,但是!一个很大的区别是compileAngularJS在数据绑定之前就已经关闭了,这意味着{{item.make}}在模板中使用没有问题.使用Angular 2,这似乎是一个禁忌,因为{{item}}它正在被解析.那么最好的方法是什么呢?使用略有不同的符号[[item]]和字符串替换整个事物似乎不是最优雅的方式...

提前致谢!

//编辑:这是一个重现问题的Plnkr.

Ric*_*sen 6

要说明ngForTemplate方法:

(从Angular 4开始,现在调用该元素<ng-template>.)

  1. <template>在外部和内部组件中使用标签,而不是<ng-content>.

  2. <li>被移动到app.component HTML,和<template>在这个组件上有一个特殊的"let-"属性它引用在该内部部件的迭代变量:

    <my-list [data]="cars">
      <template let-item>
        <li>
          <div>{{item.make | uppercase}}</div>
        </li>
      </template>
    </my-list>
    
    Run Code Online (Sandbox Code Playgroud)
  3. 内部组件也有<template>,并使用ngFor的变体,如下所示:

    <ul>
        <template #items ngFor [ngForOf]="data" [ngForTemplate]="tmpl">
            -- insert template here --
        </template>
    </ul>
    
    Run Code Online (Sandbox Code Playgroud)
  4. 分配给ngForTemplate属性的'tmpl'变量需要在组件代码中获取:

    export class MyListComponent {
        @Input() data: any[];
        @ContentChild(TemplateRef) tmpl: TemplateRef;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. @ContentChild和TemplateRef是角位,因此需要导入

    import { Component, Input, ContentChild, TemplateRef } from '@angular/core';
    
    Run Code Online (Sandbox Code Playgroud)

在这里plnkr看到你的plunkr的叉子这些变化.

对于您提出的问题,这不是最令人满意的解决方案,因为您将数据传递到列表中,您可能在外部使用ngFor.另外,附加内容(文字' - 插入模板在这里 - ')被删除,所以你想要显示它也必须在外模板上.

我可以看到,在内部组件中提供迭代(例如从服务调用中)可能有用,并且可能在代码中对模板进行一些操作.