角度数据绑定在推送到阵列时更新,无需克隆或使用可观察对象

时间:2018-10-25 15:23:09

标签: angular typescript

我是Angular的新手,我有一个“简单”问题。假设我有一个Angular组件,该组件在其类中具有一个数组形式的字段。此外,假设组件的模板中有一个数据绑定到此数组(例如,因为它在ngFor指令中使用)。由于数组上的某些事件push()(或其他变异方法)被调用后,是否有任何方法可以使Angular手动“重新评估”数据绑定,而无需克隆和重新分配它或使用带有Observable方法的变通方法

我知道这个主题在此站点上已被多次涉及,但是我想知道是否缺少我,因为我认为通常建议的进行数据绑定更新的方法很难看。

非常感谢, 约书亚

3 个答案:

答案 0 :(得分:1)

  

我是Angular的新手,我有一个“简单”问题

这不是一个简单的问题。这可能就是为什么您不愿意使用粗体提到的一种解决方案的原因。这是一个与数据突变以及Angular如何处理变化检测有关的复杂主题。

简短的摘要是这是一个 JavaScript 问题。 Angular无法通过使用===运算符来判断数组是否发生了突变,这是大多数框架(如Angular,Rect和Vue)中进行更改检测的基础。

  

由于某些事件push(),是否有任何方法可以使Angular手动“重新评估”数据绑定

问题在于,当您在数组上调用push()时,old === new的值都相等。 Angular无法确定对Array的变量引用已更改。从角度角度看,旧值和新值是相同的。

对象的属性也存在此问题。如果您具有使用对象引用的绑定,并且您对属性进行了突变。 Angular不会知道对象已更改,因此不会在该绑定上触发更改事件。

  

无需克隆和重新分配它,或使用带有Observable的变通方法

那些是最简单的方法。其他任何事情都更加复杂,以后再返回源代码时,您会想知道为什么以另一种方式来做。

我可以用此代码示例来说明问题;

 var a = [];
 var b = a;
 console.log(a === b); // prints true
 a.push({});
 console.log(a === b); // prints true

代码使a的值发生了变化,但是我们希望更改检测知道ab不再相同。由于我们两次获得true,因此Angular将忽略第二个 true 变更测试。

我们可以使用slice()

解决此问题
 var a = [];
 var b = a;
 console.log(a === b); // prints true
 a = a.slice();
 a.push({});
 console.log(a === b); // prints false

现在,第二个 test 触发器 false 触发,Angular将知道值已更改,并且更改检测将对组件和指令(即ngFor)起作用。

因此,当您需要将 push()值添加到数组时,请确保先 slice()

答案 1 :(得分:0)

您可以使用ngOnChanges()。指令的任何数据绑定属性更改时调用的生命周期挂钩。定义ngOnChanges()方法来处理更改。

有关更多信息,请检查此Doc

答案 2 :(得分:0)

我认为您在推送项目时不需要手动“重新评估”数据绑定,它可能是自动的,但是如果您共享代码,我们将拥有更好的画面。

谢谢。 安德里亚