Ser*_*giu 2 javascript angular angular-state-managmement
我来自 React,现在我已经使用 Angular 工作了几个月了。React 组件在重新渲染时仅更新必要的 HTML,而 Angular 组件在状态未发生变化时似乎会完全重新渲染。如果我直接改变状态似乎工作得很好。
这是我的非常基本的例子:
我有保存状态的主要组件:
items = [{ name: "John", age: 8 }, { name: "Jane", age: 20 }];
Run Code Online (Sandbox Code Playgroud)
在它的视图中它呈现一个项目列表:
items = [{ name: "John", age: 8 }, { name: "Jane", age: 20 }];
Run Code Online (Sandbox Code Playgroud)
item组件如下所示:
@Component({
selector: "item",
template: `
<p>
{{ item.name }}, {{ item.age }}
<input type="checkbox" />
</p>
`
})
export class ItemComponent {
@Input() item: any;
}
Run Code Online (Sandbox Code Playgroud)
我在项目组件中添加了该复选框,只是为了注意到组件何时完全重新渲染。
所以我要做的就是勾选复选框并age为该州的每个用户增加 。
如果我通过改变状态来增加它,视图将按预期更新并且复选框保持选中状态:
this.items.forEach(item => {
item.age++;
});
Run Code Online (Sandbox Code Playgroud)
但是,如果我更改age而不直接改变状态,则整个列表将重新渲染,并且不再选中该复选框:
this.items = this.items.map(item => ({
...item,
age: item.age + 1
}));
Run Code Online (Sandbox Code Playgroud)
这是CodeSandbox中的完整示例。
谁能解释一下为什么会发生这种情况,以及当我不改变状态时如何使列表不完全重新渲染?
Angular 用于渲染项目列表的NgForOf指令检查我们传递给它的数组中是否有任何更改。
如果您改变项目中的属性,那么 Angular 就会知道没有变化,因为对数组中对象的引用保持不变。
另一方面,如果您用新对象完全替换以前的对象,那么 ngForOf 就会发出重新渲染该对象的信号。
要确定对象是否更改 ngForOf 指令,请使用 DefaultIterableDiffer,它会查看 trackByFn 函数(如果我们提供了它)。如果我们不提供它,那么默认函数如下所示:
var trackByIdentity = function (index, item) {
return item;
};
Run Code Online (Sandbox Code Playgroud)
然后 Angular将此函数的结果与集合中先前的值进行比较。
trackByFn你可以像keyReact中那样思考。
所以你的解决方案可能如下所示:
*ngFor="let item of items; trackBy: trackByFn"
trackByFn(i) {
return i;
}
Run Code Online (Sandbox Code Playgroud)
https://codesandbox.io/s/angular-67vo6
| 归档时间: |
|
| 查看次数: |
5795 次 |
| 最近记录: |