【问题标题】:Display global error message in angular pages在角度页面中显示全局错误消息
【发布时间】:2019-11-05 04:30:45
【问题描述】:

我有嵌套在父页面组件中的子组件。目前我有一个事件发射器,它会向父组件发出错误事件和消息,以在遇到错误时显示。有没有办法冒泡错误消息,以便它们显示在所有页面上。我正在考虑使用 appcomponent 文件,但不知道如何处理它。

Child:
@Output() errorEmitter = new EventEmitter();

errorEmission(message: string){
    this.errorEmitter.emit(message);
  }

Parent:
<app-manage (errorEmitter)='displayError($event)'></app-manage>


displayError(message: string) {
    this.errorMessageIsOn = true;
    this.errorMessageString = message;
  }

有没有办法让它可扩展,这样我就不必为每个页面而只为每个组件重写这段代码?

【问题讨论】:

  • 可能使用服务来共享消息给所有组件或ngrx

标签: angular


【解决方案1】:

简单地说,这个想法是将错误与 UI 逻辑完全分离:

  1. 创建一个通知(toaster)组件,该组件将订阅错误、警告、信息性、成功消息
  2. 创建一个能够发送消息和通知组件以使用它们的服务。

示例notification.service.ts:

import { Injectable } from '@angular/core'
import { BehaviorSubject, Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class NotificationService {
  private readonly errorsSubject$ = new Subject<string>();

  public errors$() { 
    return this.errorsSubject$.asObservable();
  }

  public showError(message: string) : void {
    this.errorsSubject$.next(message);
  }
}

示例notification.component.ts,您的应用程序中应该只有一个实例。

import { Component, Input } from "@angular/core";
import { NotificationService } from "./notification.service";

@Component({
  selector: "notification",
  template: `
    <h2 *ngIf="(error$ | async) as error">Hello {{ error }}!</h2>
  `,
  styles: [
    `
      h1 {
        font-family: Lato;
      }
    `
  ]
})
export class NotificationComponent {
  error$ = this.notificationService.errors$();

  constructor(private readonly notificationService: NotificationService) {}
}

也是一个可以发送消息的示例组件,这可以是任何其他执行此操作的组件。

import { Component, Input } from "@angular/core";
import { NotificationService } from "./notification.service";

@Component({
  selector: "hello",
  template: `
    <button (click)="onClick()">Show error</button>
  `,
  styles: [
    `
      button {
        font-family: Lato;
      }
    `
  ]
})
export class HelloComponent {
  @Input() name: string;
  constructor(private readonly notificationService: NotificationService) {}

  onClick(): void {
    this.notificationService.showError(
      `This error has been posted on ${Date.now()}`
    );
  }
}

因此,现在只要您在任何组件中注入通知服务并通过该服务发送消息,通知组件就可以订阅它并在全球范围内显示它们。这是一个Stackblitz,表明它正在工作。

显然这是非常简化的,您需要实现更多,但这应该会让您走上正轨。

一个改进是从通知服务中删除error$ observable,只允许通知组件访问它。您可以通过实现一个内部通知服务来实现这一点,该服务将充当通知服务和通知组件之间的桥梁。你赢什么?通知服务不再公开error$ observable,只公开发送消息的方法。

notification.service.ts

import { Injectable } from "@angular/core";
import { Subject } from "rxjs";
import { NotificationInternalService } from "./notification-internal.service";

@Injectable({
  providedIn: "root"
})
export class NotificationService {
  constructor(private readonly internalService: NotificationInternalService){}

  public showError(message: string): void {
    this.internalService.errorSubject$.next(message);
  }
}

notification-internal.service.ts

import { Injectable } from "@angular/core";
import { Subject } from "rxjs";

@Injectable({
  providedIn: "root"
})
export class NotificationInternalService {
  public errorSubject$ = new Subject<string>();

  public get error$() {
    return this.errorSubject$.asObservable();
  }
}

notification.component.ts 现在引用notification-internal.service.ts

import { Component, Input } from "@angular/core";
import { NotificationInternalService } from "./notification-internal.service";

@Component({
  selector: "notification",
  template: `
    <h2 *ngIf="(error$ | async) as error">Hello {{ error }}!</h2>
  `,
  styles: [
    `
      h1 {
        font-family: Lato;
      }
    `
  ]
})
export class NotificationComponent {
  error$ = this.service.error$;

  constructor(private readonly service: NotificationInternalService) {}
}

【讨论】:

  • 一个非常简单的通知组件??,我非常喜欢这个error$ | async
  • 谢谢@malbarmawi ?
  • 谢谢@EvaldasBuinauskas 非常有帮助 - 感谢您花时间发布此解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-18
  • 2021-05-05
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
  • 1970-01-01
相关资源
最近更新 更多