当我在Angular应用中一次调用.next()时,主题订阅被触发两次

时间:2018-12-30 15:24:15

标签: javascript angular rxjs rxjs6 subject

我正在尝试创建可重用的Modal组件。 在ModalService中,我有一个Subject,以及一个对该主题调用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);
    });
  }

2 个答案:

答案 0 :(得分:0)

在您的问题中不清楚在何处以及如何调用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();
  }

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

答案 1 :(得分:0)

最好的方法是推送数组中的所有订阅并将其取消订阅到ngondestroy中。

First import the Subscription from rxjs
     import { Subscription} from 'rxjs';
    
second create global property in component     
     subscriptions: Subscription[] = [];
    
    
Third push all the subscribe in subscriptions property
    constructor(){
    this.subscriptions.push(this.Service.subject1.subscribe((result) => {
          console.log('subject1');
    
        }));
    
        this.subscriptions.push(this.dataService.subject2.subscribe((data) => {
        console.log('subject2')
    }
    
    
 Lastly unsubscribe it   
     ngOnDestroy() {
       
        this.subscriptions.forEach(sub => sub.unsubscribe());
    
    
      }