首页 文章

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

提问于
浏览
4

我在我的应用程序中使用NgRx Store .

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));
      }
  }

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

我还记录子组件“ngOnChanges”,它不会触发新值 .

3 回答

  • 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不知道要更新 .

  • 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();
                  }
              }
    
  • 0

    ngrx存储不会自动触发更改检测(也不应该),因此您不会看到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 使用 NgZone .

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

相关问题