我使用的是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[];
}
我这样使用它:
<my-list [data]="cars">
<div>{{item.make | uppercase}}</div>
</my-list>
正如你所看到的,我正在尝试定义一个内联模板,它将被我的组件使用。这是大错特错的。首先,一个数据绑定异常表示它是can't read property 'make' of undefined
。它试图从我周围的组件中读取item.make
,而不是MyListComponent
。但即使我现在暂时禁用这个:
<my-list [data]="cars">
<div>{item.make | uppercase}</div>
</my-list>
然后第二个问题出现了:
-- insert template here --
-- insert template here --
-- insert template here --
-- insert template here --
{item.make | uppercase}
所以Angular并没有复制模板来使用*ngFor
,它只是绑定了元素,并最终与最后一项相关联。
我如何得到这个工作?
我在AngularJS中遇到了同样的问题,petebacondarwin发布了一个通过编译来操作DOM的解决方案,这很棒。我在Angular 2中也有这个选项,通过在我的组件中注入ElementRef
,但是!一个很大的区别是,AngularJS中的compile
在绑定数据之前就失效了,这意味着在模板中使用{{item.make}}
没有问题。在Angular 2中,这似乎是不允许的,因为{{item}}
已经被事先解析了。那么最好的方法是什么呢?使用稍微不同的符号[[item]]
和string替换整个东西似乎不是最优雅的方式…
提前感谢!
//编辑:这是一个重现问题的Plnkr。
拼出ngForTemplate
方法:
(从Angular 4开始元素现在被称为<ng-template>
。)
-
在外部和内部组件中使用
<template>
标签,而不是<ng-content>
。 -
<li>
被移动到app.component html中,并且该组件上的<template>
有一个特殊的'let-'属性,它引用了内部组件中的迭代变量:<my-list [data]="cars"> <template let-item> <li> <div>{{item.make | uppercase}}</div> </li> </template> </my-list>
-
内部组件也有
<template>
,并使用ngFor的一个变体,如下所示:<ul> <template #items ngFor [ngForOf]="data" [ngForTemplate]="tmpl"> -- insert template here -- </template> </ul>
-
分配给ngForTemplate属性的'tmpl'变量需要在组件代码中获取:
export class MyListComponent { @Input() data: any[]; @ContentChild(TemplateRef) tmpl: TemplateRef; }
-
@ContentChild和TemplateRef是角位,所以需要导入
import { Component, Input, ContentChild, TemplateRef } from '@angular/core';
看到你的叉与这些变化在这里plnkr。
这不是你所陈述的问题的最令人满意的解决方案,因为你正在将数据传递到列表中,你还不如在外部使用ngFor。另外,额外的内容(字面'——insert template here——')会被删除,所以如果您想显示它,它也必须在外部模板上。
我可以看到,在内部组件(例如从服务调用)中提供迭代时,它可能是有用的,并且可能在代码中对模板进行一些操作。
-
<ng-content>
在*ngFor
里面不起作用,因此<li *ngFor="let item of data"> -- insert template here -- <ng-content></ng-content> </li>
不会做任何有意义的事情。所有内容都将被转包到第一个<ng-content>
https://github.com/angular/angular/issues/8563可能会解决你的一些需求。
- 在Angular 2中使用ngForTemplate时绑定事件
- ng-content选择绑定变量可能是一种方法,允许做类似于你在你的问题中演示的事情。
它要求组件的用户将内容包装在<template>
标签中。