带有数组突变的Angular2 ngFor OnPush变化检测 [英] Angular2 ngFor OnPush Change Detection with Array Mutations

查看:194
本文介绍了带有数组突变的Angular2 ngFor OnPush变化检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数据表组件( angular2-data-table )项目,为了优化渲染速度,将项目从Angular的传统更改检测更改为OnPush.

I have a data table component ( angular2-data-table ) project where we changed the project from Angular's traditional change detection to OnPush for optimized rendering speeds.

一旦实施了新的变更检测策略,就会发生一个错误,该错误引用了当数据对象发生突变(例如对象的属性更新)时表未更新.参考:

Once the new change detection strategy was implemented, a bug was filed referencing the table is not updating when the data object is mutated such as object's property updates Reference: https://github.com/swimlane/angular2-data-table/issues/255. A strong use case can be made for this type of need for things such as inline editing or external data changes to a single property in a large data collection like a stock ticker.

为解决此问题,我们添加了一个名为trackByProp的自定义trackBy属性检查器.参考:提交.不幸的是,此解决方案未能解决问题.

In an effort to resolve the issue, we added a custom trackBy property checker called trackByProp. Reference: commit. Unfortunately, this solution did not resolve the matter.

演示页面的实时重新加载下,您可以看到在以上提交正在运行,但直到单击后才更新表,从而触发更改检测.

On the demo page under live reloading you can see the demo referenced in the above commit running but not updating the table until you click thus triggering change detection.

组件的结构类似于:

Table > Body > Row Group > Row > Cell

所有这些组件都实现OnPush.我在行设置器中使用getters/setters来触发页面重新计算,如所示

all of these components implementOnPush. I'm using getters/setters in the row setter to trigger page recalculations like shown here.

对于那些实施此模式的人,我们想保留OnPush更改检测的功能,但是,由于有多个使用者的开源项目,人们可能会争论某种针对屏幕上可见行值的自定义检查功能

We'd like to stay with the OnPushchange detection for those implementing this pattern, however, as a open-source project with multiple consumers one could argue some sort of custom checking function for the visible row values on the screen.

所有说明,trackBy不会触发行单元格值的变化检测,什么是最好的方法?

All that said, trackBy is not triggering change detection in row cell values, what is the best way to accomplish this?

推荐答案

Angular2更改检测不检查数组或对象的内容.

Angular2 change detection doesn't check the contents of arrays or object.

一种变通的解决方法是仅在突变后创建阵列的副本

A hacky workaround is to just create a copy of the array after mutation

this.myArray.push(newItem);
this.myArray = this.myArray.slice();

这样this.myArray引用了另一个数组实例,Angular会识别出更改.

This way this.myArray refers a different array instance and Angular will recognize the change.

另一种方法是使用IterableDiffer(用于数组)或KeyValueDiffer(用于对象)

Another approach is to use an IterableDiffer (for arrays) or KeyValueDiffer (for objects)

// inject a differ implementation 
constructor(differs: KeyValueDiffers) {
  // store the initial value to compare with
  this.differ = differs.find({}).create(null);
}

@Input() data: any;

ngDoCheck() {
  var changes = this.differ.diff(this.data); // check for changes
  if (changes && this.initialized) {
    // do something if changes were found
  }
}

另请参见> ://github.com/angular/angular/blob/14ee75924b6ae770115f7f260d720efa8bfb576a/modules/%40angular/common/src/directives/ng_class.ts#L122

这篇关于带有数组突变的Angular2 ngFor OnPush变化检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆