下面是我的代码,我省略了组件代码的缩写:
template.html
...
<tr *ngFor="let item of getProducts(); let i = index"
[pa-attr]="getProducts().length < 6 ? 'bg-success' : 'bg-warning'">
<td>{{item.name}}</td>
</tr>
及以下是自定义属性指令代码:
@Directive({
selector: "[pa-attr]",
})
export class PaAttrDirective {
constructor(private element: ElementRef) {
console.log('been called')
}
@Input("pa-attr")
bgClass: string;
ngOnInit() {
this.element.nativeElement.classList.add(this.bgClass || "bg-success",
"text-white");
}
}
我很困惑,为什么只有第六项的颜色变为黄色(bg-warning)?是否所有项目的颜色都应更改为黄色?因为当我添加新项目时,getProducts()
的数据源发生了变化,所以getProducts().length
返回了六个项目,由于数据源发生了变化,整个<tr>
应该重新评估,因此现在每个项目的从第一到第六应该是黄色的,不是吗?那为什么只有第六项是黄色的呢?
答案 0 :(得分:1)
"since the data source changes, the whole <tr> should be reevaluated"
-此语句不正确。
*ngFor
进行了许多优化。在这种情况下,前5个<tr>
实例保持不变,并且仅添加了一个新实例。
当迭代器的内容更改时,
NgForOf
使 DOM的相应更改:
- 添加项目后,模板的新实例将添加到DOM。
- 删除项目后,其模板实例将从DOM中删除。
- 重新排列项目时,它们各自的模板在DOM中也重新排列。
Angular使用对象标识来跟踪其中的插入和删除 迭代器并在DOM中重现这些更改。
如果您在添加第6种产品时查看控制台,则只会看到一条额外的“被呼叫”消息。
由于this.bgClass
的值仅在指令的ngOnInit
挂钩期间读取,因此只有新的<tr>
实例将显示为黄色。
答案 1 :(得分:0)
我并没有做很多Angular,但这看起来就像我期望的代码所示。每次通过循环(let item of getProducts()
)时,由于逻辑原因,前5个<tr>
(表行)将应用bg-success
类[pa-attr]
属性中的所有内容,以及应用bg-warning
以外的所有内容。