Как предотвратить замену DOM в angular2 ngFor async в angularfire2?

У меня есть асинхронный список сообщений в приложении angular2 с использованием angularfire2.

<message *ngFor="let message of messages | async" [message]="message"></message>

Когда список обновляется, кажется, что все элементы в ngFor перерисовываются. Можно ли просто повторно отображать новые элементы в списке?


person okhobb    schedule 10.09.2016    source источник


Ответы (2)


Повторный рендеринг происходит, потому что вы изменили фактическую ссылку на объект при извлечении данных, в этот момент angular ngFor перерисовывает все узлы DOM. В таких случаях вы можете использовать здесь trackBy, чтобы сделать свой *ngFor умнее.

trackBy должен основываться на столбце уникальных идентификаторов, в вашем случае я мог бы сказать, что это будет message.id

<message *ngFor="let message of messages | async;trackBy:trackByFn" [message]="message"></message>

Код

trackByFn(message: any){
   // return message != null ? message.id: null;
   // OR
   return message && message.id; //more better
}
person Pankaj Parkar    schedule 10.09.2016
comment
Разве не должно быть trackBy:trackByFn вместо trackBy= trackByFn? - person Günter Zöchbauer; 10.09.2016
comment
@GünterZöchbauer Спасибо за внимание, я пропустил это :) - person Pankaj Parkar; 10.09.2016
comment
@GünterZöchbauer да. исправлено. - person okhobb; 10.09.2016
comment
Благодарю. это не совсем сработало, но ‹message *ngFor=let message of messages | async;trackBy=trackByFn [message]=message›‹/message›, где trackByFn возвращает идентификатор. - person okhobb; 10.09.2016
comment
@GünterZöchbauer Я думаю, что технически было бы лучше, чтобы trackBy=someFn как let i = index(выражение) использовало = - person Pankaj Parkar; 10.09.2016
comment
@okhobb какую версию вы используете? - person Pankaj Parkar; 10.09.2016
comment
@угловой/ядро: 2.0.0-rc.5 - person okhobb; 11.09.2016
comment
@okhobb это должно работать с tackBy:tackByFn, см. здесь - person Pankaj Parkar; 11.09.2016
comment
я думаю, что первый аргумент index. если вы хотите использовать свой собственный идентификатор, вам нужен второй аргумент. trackByFn (индекс, элемент) {возврат (элемент)? item.id : не определено; } - person okhobb; 11.09.2016
comment
@okhobb я хочу создать plunkr, чтобы просто показать, что он работает с тем, что содержится в обновленном ответе trackBy: trackByFn, а не trackBy=trackByFn - person Pankaj Parkar; 11.09.2016
comment
trackBy не исправил это для меня, мне пришлось удалить асинхронный канал и подписаться на данные: stackoverflow.com/a/49547483/ 3806701 - person cs_pupil; 01.04.2018

это лучшее решение, которое я видел.

от @jeffbcros

https://github.com/angular/angularfire2/issues/540#issuecomment-248780730

class MyComponent {
  trackFbObjects = (idx, obj) => obj.$key;
}

<message *ngFor="let message of messages | async; trackby: trackFbObjects " [message]="message"></message>
person Coşkun Deniz    schedule 22.12.2016