You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 17.3.8独立模式SSR下ngx-toastr无法关闭该如何解决

Angular 17.3.8独立模式SSR环境下ngx-toastr无法关闭

在Angular 17.3.8独立模式SSR环境中使用ngx-toastr@19.0.0时,出现以下异常:

  • 提示框的timeOut设置不生效,进度条走完后提示框仍不消失
  • 调用toastrService.clear()无法清除提示框

复现步骤

1. 创建Angular SSR应用

npx @angular/cli@17.3.8 new ng-toaster
? Which stylesheet format would you like to use? Sass (SCSS)
? Do you want to enable Server-Side Rendering (SSR) and Static Site Generation (SSG/Prerendering)? Yes

2. 安装ngx-toastr

npm install ngx-toastr --save

安装版本为"ngx-toastr": "^19.0.0"

3. 配置app.config.ts

import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideClientHydration } from '@angular/platform-browser';
import { routes } from './app.routes';
import { provideAnimations } from '@angular/platform-browser/animations';
import { provideToastr } from 'ngx-toastr';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes), 
    provideClientHydration(),
    provideAnimations(),
    provideToastr({
      timeOut: 2000,
      progressBar: true,
      progressAnimation: 'decreasing',
      closeButton: true
    })
  ]
};

4. 引入样式到styles.scss

@import 'ngx-toastr/toastr';

5. 修改app.component.ts

import { Component, inject } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { ToastrService } from 'ngx-toastr';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss'
})
export class AppComponent {
  title = 'ng-toaster';
  private readonly _toasterService = inject(ToastrService);

  constructor() {
    this._toasterService.success('Close already!');
  }

  clear(){
    console.log(`Clear`);
    this._toasterService.clear();
  }
}

6. 修改app.component.html

<h1>{{title}}</h1>
<p>Toaster please close</p>
<button type="button" (click)="clear()">Clear</button>
<router-outlet />

7. 运行应用

npm run start

问题现象

  • 访问http://localhost:4200/,提示框出现,进度条正常减少,但不会自动消失
  • 点击「Clear」按钮,控制台打印Clear,但提示框仍不消失

解决方案

问题根源是SSR环境下,toastr在服务端被渲染出来,但客户端的ToastrService实例无法关联到服务端生成的DOM元素,导致定时器和清除操作都无法作用于已渲染的提示框。

方法1:仅在浏览器环境中显示toastr

使用isPlatformBrowser判断当前环境,只在客户端初始化后显示提示框:

import { Component, inject, OnInit, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { RouterOutlet } from '@angular/router';
import { ToastrService } from 'ngx-toastr';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss'
})
export class AppComponent implements OnInit {
  title = 'ng-toaster';
  private readonly _toasterService = inject(ToastrService);
  private readonly _platformId = inject(PLATFORM_ID);

  ngOnInit(): void {
    // 仅在浏览器环境中显示toastr
    if (isPlatformBrowser(this._platformId)) {
      this._toasterService.success('Close already!');
    }
  }

  clear(){
    console.log(`Clear`);
    this._toasterService.clear();
  }
}

方法2:延迟到客户端 hydration 完成后执行

利用Angular 16+支持的AfterNextRender钩子,确保在客户端完全初始化后再调用toastr:

import { Component, inject, AfterNextRender } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { ToastrService } from 'ngx-toastr';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss'
})
export class AppComponent implements AfterNextRender {
  title = 'ng-toaster';
  private readonly _toasterService = inject(ToastrService);

  ngAfterNextRender(): void {
    // 在客户端首次渲染完成后显示toastr
    this._toasterService.success('Close already!');
  }

  clear(){
    console.log(`Clear`);
    this._toasterService.clear();
  }
}

原理说明

在SSR模式下,服务端会先渲染页面并生成toastr的DOM元素,但此时客户端的ToastrService还未初始化,无法绑定到这些服务端生成的元素上。通过限制toastr仅在客户端环境中创建,确保DOM元素和服务实例一一对应,这样定时器和清除操作就能正常工作。

内容的提问来源于stack exchange,提问作者Dimitris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 11:34:54