angular - *ngFor - ngrx aracılığıyla dizi güncellendiğinde DOM'u güncelle
Bir diziden değerleri göstermek için *ngFor kullanıyorum:
[
{
id: 1,
name: 'item1'
},
{
id: 2,
name: 'item2'
}
]
html :
<div *ngFor="let item of (items$ | async); trackBy: trackById;">
// more html to display data
</div
ts :
items$: Observable<any>;
trackById = trackByProperty('id');
ngOnInit() {
this.items$ = this.store.pipe(select(selectors.itemsSelector));
}
trackByProperty<T = any>(property: keyof T) {
return (index: number, object: T) => object[property];
}
Bu amaçlandığı gibi çalışıyor, ngFor items$ array içindeki doğru ve güncel değerleri alıyor
Sorunum, ngrx kullanarak items$ dizisini güncellediğimde, yeni diziyi yakalayamaması ve DOM'u güncelleyememesi.
İşte ngrx kullanarak veri akışı
Diziye eklemek için yeni bir nesne göndererek işlemi (action) reduce ediciye (reducer) gönderin.
this.store.dispatch(new actions.UpdateArray( { id: 3, name: 'item3' } ) );Reducer bu eylemi alır ve store durumunu güncellenmiş dizi ile günceller (yeni öğeyi alır ve diziye ekler).
case actions.UPDATE_ARRAY: { const newItem = action.payload; const items = state.items; items.push(newItem); return { ...state, items }; }Seçici güncellemeleri.
Reducer'da action.payload'u loglarken state'in doğru şekilde güncellendiğini onaylayabilirim.
Biri, neden *ngFor içinde güncellenmiş bir dizi almadığımı biliyor mu?
Bahsetmeyi unuttum, ama bileşenimde değişiklik algılaması olarak changeDetection: ChangeDetectionStrategy.OnPush kullanıyorum
Güncelle
DOM'un aslında bileşene tıkladığınızda güncellendiğini fark ettim. Bunun için tıklamak zorunda kalmadan güncellenmesini istiyorum.
Cevap #1
Bu, NgRx seçicilerinin bazen istenmeyen davranışa yol açabilen Memoization kullanmasından dolayı olabilir.
Değişiyor
case actions.UPDATE_ARRAY: {
const newItem = action.payload;
const items = state.items;
items.push(newItem);
return {
...state,
items
};
}
için
case actions.UPDATE_ARRAY: {
const newItem = action.payload;
const items = [...state.items, newItem]; // <-- creates new instance
return {
...state,
items
};
}
Sorunu çözmeli.
