Angular : 变量异步更改时视图未更新
Angular : View not updating when variable changed asynchronously
这里我在App.Component.ts订阅通知服务的notification$。一切进展顺利,我已经更改了 App.Component.ts 的 ngOnInit 中的值,但相应地它的视图不是 rendering/updating。
但是当继续另一个视图时,我发现视图相应地发生了变化(但不是同时它的值发生了变化)。
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}`);
}
}
如果稍后反映了更改,那一定是更改检测问题。
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();
});
}
这里我在App.Component.ts订阅通知服务的notification$。一切进展顺利,我已经更改了 App.Component.ts 的 ngOnInit 中的值,但相应地它的视图不是 rendering/updating。
但是当继续另一个视图时,我发现视图相应地发生了变化(但不是同时它的值发生了变化)。
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}`);
}
}
如果稍后反映了更改,那一定是更改检测问题。
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();
});
}