ngFor trackBy по-прежнему повторяет рендеринг DOM?

Я активировал trackBy в моем ngFor и подтвердил, что он вызывается и работает, но я все еще замечаю, что DOM повторно отображается в моем браузере, что приводит к мерцанию строк. Что здесь происходит? В Angular1 я вижу в моем браузере / отладчике Chrome, что DOM не обновляется / не заменяется при использовании track by item.id и мерцания не происходит, почему это не так в angular2. Есть ли какая-то ошибка в моем коде или что-то происходит под капотом, о чем я не знаю, на самом деле делая что-то хорошее?

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

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

ИЗМЕНИТЬ. Я обнаружил, что ошибка находится в наблюдаемом в моей службе API, вызывая это, но до сих пор не знаю, почему.

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);
}

Решение

Решено с использованием того же наблюдаемого 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);

person jonassvensson    schedule 22.10.2016    source источник
comment
Вы можете опубликовать весь свой код, пожалуйста?   -  person Bazinga    schedule 22.10.2016


Ответы (1)


Я не уверен, как вы реализуете функцию изменения, но я реализовал этот код, и он отлично работает:

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 -> inspect element мерцает только добавленный элемент.

Рабочий плункер

person Bazinga    schedule 22.10.2016
comment
Я подтвердил, что это работает. И я мог бы подтвердить, что он работает, если просто добавлю статические данные с помощью Observable.of ([...]) в свой список, но не из моей службы API. Я обновляю свой вопрос. - person jonassvensson; 22.10.2016