Angular2的一个短板就是当需要展示一个集合/数组的成员时(通常listview、treeview、table、datagrid等等模型),基本上没有办法绕开*ngFor
*ngFor实际上是*ngFor和*ngForOf两个template directive的合体形式,用户也可以自己实现ngFor(比如写成*ngEach="let item of items;"),但是本质上还是绕不开这个*ngFor的模板语法
这样的缺点是什么呢?那就是用户很难用一个Component封装对一个数组的显示逻辑同时自定义显示的模板。
WPF当中ItemsControl的设计就是封装逻辑,但是内部每个Item呈现是用的ItemTemplate/DataTemplate。但是Angluar2在这个问题上出现很大的问题,简单地说就是无法重复利用带有ngFor逻辑的Component来展示不同的内容。
1、在*ngFor模板当中嵌入transclusion的<ng-content></ng-content>。结果这个是不工作的,因为<ng-content></ng-content>的默认context是整个template对应的class而不是局部的Component,所以无法让<ng-content></ng-content>来呈现*ngFor的child。
2、就是让套在外层的ItemsSource控件来管理数组展示的逻辑(比如分页、筛选、查询等等)。但是同样的问题还是ItemsSource是不存在于当前template对应的class上的。所以在一个Component内部嵌套<ng-content></ng-content>的方案不论如何都是行不通的。
<div [ItemsSource]=Items>
<div *ngFor="let item of ItemsSource">
</div>
</div>
3、所以解决方案必须还是回到Compile的问题上。
<div [ItemsSource]=Items [ItemTemplate]="/template.html#button">
</div>
in template.html:
<div id="button" class="btn" [class.checked]="Parent.SelectedItem == Item">
{{Item.Name}}
</div>
这实际上是一个无奈的work around。在Angular1当中,我可以直接把ItemTemplate嵌入到ItemsSource当中,但是Angular2是预编译的,在编译过程中就把它认为不合法的语法去掉了,或者会对不能到达的引用报错。这样导致在Angular2的component template当中嵌入template几乎是不可能的,但是我又需要在Angular2当中写一个template就可以呈现数据而不要对它做类定义。
所以构造这样一个能够管理内部集合元素的Angular2控件必须能够让它进行编译。
--
FROM 110.23.10.*