如何在页面加载时触发 Toast?

How to trigger Toast on page load?

我正尝试在登录页面中使用 <p-toast> 以在用户登录时显示通知消息。

<p-toast position="top-center" key="tc"></p-toast>

然后在我的组件中声明消息。

ngOnInit() {

    // add toasts
    this.messageService.addAll([
      {key: 'tc', severity: 'info', summary: '30 Nov 2020', detail: 'Important message 1'},
      {key: 'tc', severity: 'info', summary: '30 Nov 2020', detail: 'Important message 2'}
    ]);

    // do other stuff

}

这行不通。为了确认这不是我的 toast 或消息的问题,我将消息放在页面上的 onClick() 事件中并手动触发它, 起作用。

如何让 Toasts 在页面加载时触发?

尝试使用 AfterViewInit

问题可能是因为 HTML 尚未呈现,因此请尝试以下操作。这是一个 Angular 生命周期挂钩,仅在 HTML 已初始化时触发。

一定要将它添加到您正在使用它的 class 中,就像下面的代码片段一样,对于不需要 HTML 的其他逻辑,继续使用 ngOnInit待初始化并可访问。

class MyComponent implements AfterViewInit, ngOnInit {

  ngAfterViewInit() {
    this.messageService.addAll(
    [{key: 'tc', severity: 'info',
    summary: '30 Nov 2020', detail: 'Important message 1'},
    {key: 'tc', severity: 'info',
    summary: '30 Nov 2020', detail: 'Important message 2'}]);
  }

  ngOnInit() {
  //for other logic that does not require the HTML to be initialized.
  }

}

如果您在使用 ExpressionHasChangedAfterItHasBeenCheckedError 时遇到任何问题,那么您也可以使用不同的生命周期挂钩来查找要初始化的视图。

这将是 AfterContentInit,其用法与上述示例完全相同。举个例子,哪个最适合你。如果最简单的解决方案是 setTimeout,那么如果它不会给您带来其他问题,请继续使用。建议在使用框架时使用 Angular 对您有利。

You have to send the messages once the view is initialized.

但是,通过触发 ngAfterViewInit 挂钩中的消息,您可能会得到一个 ExpressionChangedAfterItHasBeenCheckedError

以下是避免此错误的解决方案:

第一个解决方案是在初始化所有内容后使用 setTimeout 调用发送消息。

Here is a simple Stackblitz example

ngAfterViewInit() {
    setTimeout(() => {
        this.messageService.addAll([
            {key: 'tc', severity: 'info', summary: '30 Nov 2020', detail: 'Important message 1'},
            {key: 'tc', severity: 'info', summary: '30 Nov 2020', detail: 'Important message 2'}
        ]);
    })
}

另一种解决方案是使用 ChangeDetectorRef (see this article):

强制更改检测
constructor(private messageService: MessageService, private cd: ChangeDetectorRef) { }

ngAfterViewInit() {
    this.messageService.addAll([
        {key: 'tc', severity: 'info', summary: '30 Nov 2020', detail: 'Important message 1'},
        {key: 'tc', severity: 'info', summary: '30 Nov 2020', detail: 'Important message 2'}
    ]);
    this.cd.detectChanges()
}

我相信,无论何时您从 ngOnInit 启动诸如此类的任务,例如 toast 消息或其他需要等待 Init 完成的异步调用,您都可以将您的调用与其余部分直接内联你的代码只要你使用setTimeout。不需要 ngAfterInit。你可以为此感谢(或诅咒)单线程JavaScript。