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

Angular订阅响应重复触发问题求助:弹窗服务调用后响应次数递增

问题分析与解决方案

问题根源

你遇到的重复响应问题,核心原因是PopupDialogService中使用了全局唯一的Subject实例。每次调用confirmationPopup方法时,返回的都是同一个Subject的Observable;而组件每次点击按钮都会新增一个订阅,这些订阅不会自动取消。后续每次调用mySubject.next(true)时,所有已存在的订阅都会收到通知,导致响应次数随点击次数递增。

修复方案

方案1:每次调用创建独立的Subject(推荐)

修改popupDialog.service.ts,为每个弹窗请求创建独立的Subject,确保数据流隔离,同时处理取消逻辑并完成Subject避免内存泄漏:

import { Injectable } from "@angular/core";
import { Observable, Subject } from "rxjs";
import Swal from 'sweetalert2'

@Injectable()
export class PopupDialogService {

    confirmationPopup(textDetail?: string): Observable<boolean> {
        // 为每个弹窗创建独立的Subject
        const dialogSubject = new Subject<boolean>();
        
        Swal.fire({
            title: 'Are you sure?',
            text: textDetail,
            icon: 'success',
            showConfirmButton: true,
            showCancelButton: true,
        }).then((result) => {
            // SweetAlert2中确认状态用isConfirmed判断,而非value
            dialogSubject.next(result.isConfirmed);
            dialogSubject.complete(); // 完成流,自动清理订阅
        }).catch(() => {
            dialogSubject.next(false);
            dialogSubject.complete();
        });
        
        return dialogSubject.asObservable();
    }
}

方案2:直接利用SweetAlert2的Promise转Observable

SweetAlert2的fire()方法本身返回Promise,可直接将其转为Observable,代码更简洁:

import { Injectable } from "@angular/core";
import { from, Observable } from "rxjs";
import Swal from 'sweetalert2'

@Injectable()
export class PopupDialogService {

    confirmationPopup(textDetail?: string): Observable<boolean> {
        const swalPromise = Swal.fire({
            title: 'Are you sure?',
            text: textDetail,
            icon: 'success',
            showConfirmButton: true,
            showCancelButton: true,
        }).then(result => result.isConfirmed);
        
        // 将Promise转为Observable
        return from(swalPromise);
    }
}

组件优化(可选但推荐)

在组件订阅时添加take(1)操作符,确保只接收一次结果后自动取消订阅,进一步避免潜在的内存泄漏:

import { take } from 'rxjs/operators';
// ...

confirmFeatureProductDialog(product){
    const message = "Do you want to set this product?";
    this._popupDialogService.confirmationPopup(message)
      .pipe(take(1)) // 仅接收一次数据流,自动取消订阅
      .subscribe((res) => {
        console.log("Running");
        if(res){
          this.featureProduct(product._id);
        }
      });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:05:11