ngFor trackBy stil重新渲染DOM?

时间:2016-10-22 19:44:10

标签: angular ngfor angularjs-track-by

我在ngFor中激活了trackBy,我确认它已被调用并正常工作,但我仍然注意到DOM在我的浏览器中重新渲染,导致行闪烁。这里发生了什么?在Angular1中,我可以在浏览器/ chrome调试器中看到,当使用track by item.id时没有更新/替换DOM,并且没有闪烁发生,为什么在angular2中不是这种情况。我的代码中是否存在一些错误,或者是否有些事情发生在我不知道实际上做得不好的事情之下?

    <tr *ngFor="let item of items| async; trackBy:itemTrackBy">

    itemTrackBy(index: number, item: MyItem) {
        return item.id;
    }

修改 我跟踪错误是在我的API服务中的observable导致这个,但仍然不知道为什么。

this.items= this.apiService.getItems(searchText).share();


getItems(search?: string): Observable<Item[]> {
    let searchParams = new URLSearchParams();
    if (search) {
        searchParams.set('searchText', search);
    }
    return this.http
        .get(API_BASE_URL + '/items', {search: searchParams})
        .map(response => response.json())
        .catch(this.handleError);
}

解决方案

使用相同的observable this.items解决,而不是每次重新加载新数据时都用新的替换它。

this.items = Observable.concat(Observable.of(''), this.searchInput.valueChanges)
            .debounceTime(200)
            .map((value:string) => value.trim())
            .distinctUntilChanged()
            .switchMap(search => this.apiService.getItems(searchText);

1 个答案:

答案 0 :(得分:4)

我不确定你是如何实现更改功能的,但是我已经实现了这个代码并且工作正常:

export class AppComponent {
  episodes = Observable.of([
    { title: 'Winter Is Coming', id: 0 }
  ]);

  add() {
    this.episodes =  Observable.of([
      { title: 'Winter Is Coming', id: 0 },
      { title: 'The Kingsroad', id: 1 }
    ])
  }

  itemTrackBy(index: number, item) {
    return item.id;
  }
}

<button (click)="add()">Add</button>
<ul>
  <li *ngFor="let episode of episodes | async; trackBy: itemTrackBy">
    {{episode.title}}
  </li>
</ul>

当您点击添加按钮时,您将在devtools中看到 - &gt;检查元素只添加项目闪烁。

Working plunker