首页 > 解决方案 > Angular:当变量异步更改时视图不更新

问题描述

这里我在 App.Component.ts 中订阅 Notification 服务的 notification$。一切都很顺利,我在 App.Component.ts 的 ngOnInit 中更改了值,但它的视图没有相应地呈现/更新。

但是当继续另一个视图时,我发现视图已经相应地发生了变化(但不是同时它的值发生了变化)。

App.Component.ts :

export class AppComponent implements OnInit {
      notification: string;
      public showNotification: boolean = true;
     constructor(private notificationService: NotificationService) {}
    ngOnInit() {  
        this.notificationService
          .notification$
          .subscribe(message => {
            debugger;      // message is here 
            this.showNotification = true;
              this.notification = message;       
          });
      }
    }

通知服务:

import { Injectable } from '@angular/core';    
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';    
import 'rxjs/add/operator/publish';
import { Subject } from 'rxjs/Subject';    

@Injectable()
export class NotificationService {
  private _notification: BehaviorSubject<string> = new BehaviorSubject(null);
  readonly notification$: Observable<string> = this._notification.asObservable().publish().refCount();    
  constructor() { }    
  notify(message) {        
    this._notification.next(message);
    //setTimeout(() => this._notification.next(null), 3000);
  }    
}

错误服务:

import { ErrorHandler, Injectable, Injector } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { Router } from '@angular/router';    
import * as StackTraceParser from 'error-stack-parser';   
import { NotificationService } from '../_common/notification.service';    

@Injectable()
export class ErrorsService implements ErrorHandler {
  constructor(
    private injector: Injector
  ) { }

  handleError(error: Error | HttpErrorResponse) {       
    const notificationService = this.injector.get(NotificationService);        
    if (error instanceof HttpErrorResponse) {     
      return notificationService.notify(`${error.status} - ${error.message}`);
    }
}

标签: angularangular5observablesubscription

解决方案


如果稍后反映更改,则必须是更改检测问题。Http 响应回调之后通常会运行更改检测,但如果您有 ChangeDetectionStrategy.OnPush,您的组件将不会被标记为检查。您可以明确地执行此操作。只需注入 ChangeDetectorRef实例并markForCheck()在必要时调用其方法:

    constructor(private notificationService: NotificationService, private cd: ChangeDetectorRef) {}

    ngOnInit() {  
        this.notificationService
          .notification$
          .subscribe(message => {
            debugger;      // message is here 
            this.showNotification = true;
            this.notification = message;
            this.cd.markForCheck();
            // if markForCheck didn't help, try to trigger change detection mannually:
            // this.cd.detectChanges(); 
          });
      }

推荐阅读