来自 angular2 的 nfFor 阻止更新嵌套标签元素

nfFor from angular2 prevent update of nested tag element

我尝试从Angular开始 2.使用稳定版2.0.0。 我想更新列表的子列表。我从服务中获得的每个列表。为此,在 angular2 中,我对这两个部分都使用了 ngFor。

问题: 当我将 ngFor 用于上层列表时,子列表不想更新。这怎么能解决? 当我仅将 ngFor 用于子列表时 - 一切正常(我只能更新子列表)。

Link on plunker:

  1. app.ts - 这里是上面的列表
  2. race.component.ts - 带有更新按钮的子列表元素

那是因为你每次 return 新数组。

list():Array<any>{
  return [{name: "London"}, {name: "Paris"}];
}

Angular2 通过以下方式将旧数组与新数组匹配:

NgFor 指令 (https://github.com/angular/angular/blob/2.0.2/modules/%40angular/common/src/directives/ng_for.ts#L122-L127)

NgFor.prototype.ngDoCheck = function () {
  if (this._differ) {
    var changes = this._differ.diff(this.ngForOf);
    if (changes) this._applyChanges(changes);
  }
};

下一个函数在 diff 方法中触发:

function looseIdentical(a, b) {
  return a === b || typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b);
}

在 javascript {} === {} 将永远是 false

因此您的列表将始终被重新绘制。

我看到有两种解决方法:

1) 使用 array 而不是 returns array

的函数

分量

list = [{name: "London"}, {name: "Paris"}];

html

*ngFor="let race of list"

Plunker Example

2) 通过 trackBy 选项自定义默认跟踪算法 ngFor 指令:

分量

trackByFn(index, race) {
  return index;
}

或者更好一点使用 unique id:

trackByFn(index, race) {
  return race.id
}
list():Array<any>{
  return [{id: 1, name: "London"}, {id: 2, name: "Paris"}];
}

并在 html 中:

*ngFor="let race of list(); trackBy: trackByFn"

Plunker Example

查看有关 trackBy 的更多详细信息: