首页 > 解决方案 > 当我在 Angular 应用程序中调用 .next() 一次时,主题订阅被触发两次

问题描述

我正在尝试创建一个可重用的模态组件。在 ModalService 中,我有一个主题,以及一个在主题上调用 next() 的方法。ModalComponent 订阅该主题,但每当调用服务中的方法时,观察者的下一个函数都会触发两次。有谁知道这是什么原因?

export class ModalService { 
  openModal = new Subject(); 

  constructor() { } 

  open(cmp) { 
     this.openModal.next(cmp); 
   } 
}

模态组件:

export class ModalComponent implements OnInit {
  component: ComponentRef<any>;

  @ViewChild('entry', { read: ViewContainerRef }) entry: ViewContainerRef;

  constructor(
    private resolver: ComponentFactoryResolver,
    private modalService: ModalService
  ) {}

  ngOnInit() {
    this.modalService.openModal.subscribe(cmp => {

      // CALLD TWICE EVRY TIME THE SERVICE CALLS .next()
      console.log(cmp);
    });
  }

标签: javascriptangularrxjsrxjs6subject

解决方案


您的问题不清楚在哪里以及如何open()调用方法。是被open()调用两次还是被subscribe()触发两次?

但是,如果您想与订阅者共享最后一个值,您可以shareReplay()pipe()这样使用:

export class ModalService { 
  openModalSubject = new Subject(); 
  openModal = this.openModalSubject.asObservable().pipe(shareReplay());
  constructor() { } 

  open(cmp) { 
     this.openModalSubject.next(cmp); 
   } 
}

更新

在您的模态组件中,您需要unsubscribe从可观察对象中导航。你可以通过两种方式做到这一点。

第一种方式:

 modalSubscription: Subscription;

 ngOnInit() {
    this.modalSubscription = this.modalService.openModal.subscribe(cmp => {

      // CALLD TWICE EVRY TIME THE SERVICE CALLS .next()
      console.log(cmp);
    });
  }

  ngOnDestroy(){
    this.modalSubscription.unsubscribe();
  }

第二种方式:

 unsubscribeSignal: Subject<void> = new Subject();

 ngOnInit() {
    this.modalSubscription = this.modalService.openModal
    .pipe(
       takeUntil(this.unsubscribeSignal.asObservable()),
    )
    .subscribe(cmp => {

      // CALLD TWICE EVRY TIME THE SERVICE CALLS .next()
      console.log(cmp);
    });
  }

  ngOnDestroy(){
    this.unsubscribeSignal.next();
  }

我更喜欢第二种方式。这样,您可以一次取消订阅多个 observable。


推荐阅读