Subject Subscription is triggered twice when I cal

2019-08-21 18:18发布

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

Modal Component:

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

1条回答
Melony?
2楼-- · 2019-08-21 18:56

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

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

UPDATE

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

First Way:

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

Second Way:

 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.

查看更多
登录 后发表回答