http://www.open-open.com/lib/view/open1461113267205.html
如果你想获取的元素不在你的组件模版定义里怎么办?举个例子,假设你有个列表组件,允许用户自定义各列表项,然后你想跟踪列表项的数量。
当然你可以用 @ContentChildren 来获取组件里的“内容”(那些用户自定义,然后映射到你组件里的内容),但因为这些内容可以是任意值,所以是没办法向刚才那样通过 local variable 来追踪她们的。
一种方法是,要求用户给他将要映射的列表项都加上预定义的 local variable 。这样的话,代码可以从上面例子改成这样:
@ContentChildren 和 local variable (不推荐)
// user code <my-list> <li *ngFor="#item of items" #list-item> {{item}} </li> </my-list> // component code @Component({ selector: 'my-list', template: ` <ul> <ng-content></ng-content> </ul> ` }) export class MyList implements AfterContentInit { @ContentChildren('list-item') items: QueryList<ElementRef>; ngAfterContentInit() { // do something with list items } }
可是,这需要用户写些额外的内容( #list-item ),真心不怎么优雅!你可能希望用户就只写 <li> 标签,不要什么 #list-item 属性,那肿么办?
解决方案: @ContentChildren 配合 li 选择器指令
介绍一个好方案,用 @Directive 装饰器,配合他的 selector 功能。定义一个能查找/选择 <li> 元素的指令,然后用 @ContentChildren 过滤用户映射进当前组件里的内容,只留下符合条件的 li 元素。
@ContentChildren 配合 @Directive (推荐)
// user code <my-list> <li *ngFor="#item of items"> {{item}} </li> </my-list> @Directive({ selector: 'li' }) export class ListItem {} // component code @Component({ selector: 'my-list' }) export class MyList implements AfterContentInit { @ContentChildren(ListItem) items: QueryList<ListItem>; ngAfterContentInit() { // do something with list items } }
注:看起来只能选择 <my-list> 里的 li 元素(例如: my-list li ),需要注意的是,目前 angular2 尚不支持"parent-child"模式的选择器。如果需要获取组件里的元素,用 @ViewChildren 、 @ContentChildren 这类queries是最好的选择