2016-10-22 2 views
1

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

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

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

EDIT Я отследил ошибку, чтобы быть в наблюдаемой в моей службе 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); 
+0

Вы можете разместить весь свой код, пожалуйста? – Bazinga

ответ

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 - > проверить элемент только мерцание добавленного товара.

Working plunker

+0

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

+0

@patrickjane приятный exmaple с демо. – micronyks