当我在Angular应用中一次调用.next()时,主题订阅被触发两次 [英] Subject Subscription is triggered twice when I call .next() once in Angular app

查看:883
本文介绍了当我在Angular应用中一次调用.next()时,主题订阅被触发两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建可重用的Modal组件. 在ModalService中,我有一个Subject,以及一个对该主题调用next()的方法. ModalComponent订阅了该主题,但是每当调用服务中的方法时,观察者的下一个函数都会触发两次. 有人知道是什么原因造成的吗?

i'm trying to create a reusable Modal component. in a ModalService i have a Subject, and a method that that calls next() on the subject. The ModalComponent subscribes to that subject, but whenever the method in the service is being called, the next function of the observer gets triggers twice. Anyone know what causes this?

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);
    });
  }

推荐答案

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

It is not clear in your question where and how open() method is called. Is it the open() called twice or subscribe() triggered twice?

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

But if you want to share the last value with the subscribers you could use shareReplay() in pipe() like this:

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

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

更新

在模态组件中,当从其导航时,您需要从可观察对象中返回unsubscribe.您可以通过两种方式做到这一点.

And in your modal component, you need to unsubscribe from the observable when navigating from it. You can do it two ways.

第一种方式:

 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();
  }

我主要喜欢第二种方式.这样,您可以一次取消订阅多个可观察的对象.

I prefer the second way mostly. This way, you can unsubscribe more than one observable at once.

这篇关于当我在Angular应用中一次调用.next()时,主题订阅被触发两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆