Angular 2异步管道不会使用Observable呈现新值

时间:2016-08-26 10:50:58

标签: angular typescript pipe ngrx

我在我的应用中使用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;它并没有以新的价值发起。

3 个答案:

答案 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)。

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

  1. 启用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();
            });
        }
    }
    
  2. 第二种方法是注入ChangeDetectorRef并在订阅中调用detectChanges()。但是不要这样做。并且不要使用NgZone

  3. ngrx + ChangeDetectionStrategy.OnPush是提高变更检测效果的好方法。