5

我在我的应用程序中使用 NgRx 商店。

主页.html

<list-objects
      [array]="array| async"
      (Edit)="Edit($event)"
      (Delete)="Delete($event)"
 ></list-objects>

主页.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));
      }
  }

当我编辑数组项时,异步管道不会更新视图,但“数组”对象中的值是正确的(订阅内的 console.log 显示更新的值)。当我单击 DOM 中的某个位置(打开模式,单击按钮...)时,查看带有新值的更新。

我还登录了子组件“ngOnChanges”,它不会以新值触发。

4

3 回答 3

0

ngrx store 不会自动触发更改检测(也不应该),因此您看不到 UI 更新。只有几件事会自动触发更改检测:UI 输入(点击、按键等)、HTTP 响应、计时器(setTimeout 和 setInterval)。

您可以通过两种方式解决您的问题:

  1. 启用changeDetection: ChangeDetectionStrategy.OnPush然后使用订阅显式更新您的数组,在这种情况下,您需要调用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();
            });
        }
    }
    
  2. 第二种方式是注入ChangeDetectorRef并调用detectChanges()订阅。但不要这样做。并且不要使用NgZone它。

ngrx + ChangeDetectionStrategy.OnPush是提高变更检测性能的好方法。

于 2017-05-13T10:06:44.387 回答
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();
              }
          }
于 2016-10-17T21:25:49.780 回答
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 不知道要更新。

于 2016-08-26T13:01:01.767 回答