我在我的应用中使用NgRx商店。
Home.html中
<list-objects
[array]="array| async"
(Edit)="Edit($event)"
(Delete)="Delete($event)"
></list-objects>
Home.ts
export class HomePage {
public array: Observable<itm[]>;
constructor(){
this.array= this.store.select(state => state.array);
this.array.subscribe((a) => {
console.log(a); //VALUES OK
}
}
Edit(event){
this.store.dispatch(this.actions.updateItem(event.item));
}
}
当我编辑一个数组项时,异步管道不会更新视图,而是更新&#34; array&#34;对象是更正的(subscribe中的console.log显示更新的值)。当我点击DOM中的某个位置(打开模态,单击按钮......)时,使用新值查看更新。
我也记录了子组件&#34; ngOnChanges&#34;它并没有以新的价值发起。
答案 0 :(得分:0)
尝试这样的事情:
(注意此代码未经过测试)。
<list-objects
[array]="array"
(Edit)="Edit($event)"
(Delete)="Delete($event)"
></list-objects>
export class HomePage {
public array: itm[];
constructor( private zone:NgZone ){
this.store.select(state => state.array).subscribe((a) => {
this.zone.run(() => {
this.array = a;
});
}
}
Edit(event){
this.store.dispatch(this.actions.updateItem(event.item));
}
}
我已从模板中删除了异步管道,并直接分配了数组。通过在this.zone.run中执行此操作,摘要周期将触发,您的模板将重新呈现。
摘要周期通常仅在许多预定义的情况下触发,例如Http方法回调,UI输入。这些都没有发生在这里,因此Angular不知道更新。
答案 1 :(得分:0)
尝试:
constructor(private changeDetector: ChangeDetectorRef) {
this.array= this.store.select(state => state.array);
this.array.subscribe((a) => {
console.log(a); //VALUES OK
this.changeDetector.markForCheck();
}
}
答案 2 :(得分:0)
ngrx store不会自动触发更改检测(也不应该),因此您不会看到UI更新。只有几件事可以自动触发变化检测:UI输入(点击,按键等...),HTTP响应,定时器(setTimeout和setInterval)。
您可以通过两种方式解决问题:
启用changeDetection: ChangeDetectionStrategy.OnPush
,然后使用subscribe显式更新您的数组,在这种情况下,您需要调用markForCheck()
:
import { ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
@Component({
...,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class HomePage {
public array: itm[];
constructor(private ref: ChangeDetectorRef) {
this.store.select(state => state.array).subscribe(a => {
this.arr = a;
this.ref.markForCheck();
});
}
}
第二种方法是注入ChangeDetectorRef
并在订阅中调用detectChanges()
。但是不要这样做。并且不要使用NgZone
。
ngrx + ChangeDetectionStrategy.OnPush
是提高变更检测效果的好方法。