【问题标题】:Why is my Event Emitter not catching observables?为什么我的 Event Emitter 没有捕捉到 observables?
【发布时间】:2022-08-15 02:04:59
【问题描述】:

我创建了一个ComponentMessengerService,它使用一个事件发射器来允许两个子组件之间的通信。 input 组件应该通过在其构造函数中使用注入服务将信息发送到output 组件。

Epic 只是我制作的自定义模型。

组件信使服务源码:

@Injectable({
  providedIn: \'root\'
})
export class ComponentMessengerService {
  epicNumberUpdated = new EventEmitter<string>();
  epicTitleUpdated = new EventEmitter<string>();
  epicListUpdated = new EventEmitter<Epic[]>();

  sendEpicNumber(epicNumber: string){
    this.epicNumberUpdated.emit(epicNumber);
  }

  sendEpicTitle(epicTitle: string){
    this.epicTitleUpdated.emit(epicTitle)
  }
  
  sendEpicList(epicList: Epic[]){
    this.epicListUpdated.emit(epicList)
  }
}

输出组件源码:

export class OutputComponent implements OnInit {

  public epicTitle: string;
  public epicNumber: string;
  public epicList: Epic[] = [];

  constructor(private componentMessenger: ComponentMessengerService) {
    this.subscribeAll();
  }

  subscribeAll(){
    this.componentMessenger.epicListUpdated.subscribe(
      (epicList: Epic[]) => {
        this.epicList = epicList; })
    this.componentMessenger.epicTitleUpdated.subscribe(
      (epicTitle: string) => { this.epicTitle = epicTitle })
    this.componentMessenger.epicNumberUpdated.subscribe(
      (epicNumber: string) => {
        this.epicNumber = epicNumber; })
  }
}

输出的属性是数据绑定到 html 元素的,一旦组件的属性接收到 observable,就应该显示出来。我已经调试了我的应用程序并且可以确认input 组件确实在发送可观察数据。不幸的是,当我尝试在 subscribeAll() 中添加 console.log() 语句来验证事件发射器是否接收到任何数据时,这行代码从未执行过。

  • “两个子组件之间的通信..” - 这些是兄弟姐妹吗..?
  • 是的,它们属于同一个父组件。此外,我还有另一个具有类似设置的父组件,其中兄弟组件也使用相同的服务,并且工作正常。

标签: angular observable angular-event-emitter


【解决方案1】:

您是否尝试在 ngOnInit 中调用 subscribeAll() 方法?

Difference between Constructor and ngOnInit

更新

我会通过使用“Subject”而不是 EventEmitter 来解决问题,我认为 EventEmitter 需要与 @Output() 一起使用。

【讨论】:

  • 实际上,我已经尝试过两者。
  • 我会通过使用“Subject”而不是 EventEmitter 来解决问题,我认为 EventEmitter 需要使用 @Output
【解决方案2】:

我们有SubjectBehaviorSubject

@Injectable({
  providedIn: 'root'
})
export class ComponentMessengerService {
  epicNumberUpdated$ = new Subject<string>();
  epicTitleUpdated$ = new Subject<string>();
  epicListUpdated$ = new Subject<Epic[]>();

  sendEpicNumber(epicNumber: string): void {
    this.epicNumberUpdated$.next(epicNumber);
  }

  sendEpicTitle(epicTitle: string): void {
    this.epicTitleUpdated$.next(epicTitle)
  }
  
  sendEpicList(epicList: Epic[]): void {
    this.epicListUpdated$.next(epicList)
  }
}

并且不要忘记 Observables 的取消订阅,因为您可能会发生内存泄漏。

export class OutputComponent implements OnInit, OnDestroy {
  epicTitle: string;
  epicNumber: string;
  epicList: Epic[] = [];

  private unsubscribe$ = new Subject<void>();

  constructor(private componentMessenger: ComponentMessengerService) {}

  ngOnInit(): void {
    initializeListeners();
  }

  ngOnDestroy(): void {
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
  }

  initializeListeners(): void {
    this.componentMessenger.epicListUpdated$
      .pipe(takeUntil(this.unsubscribe$))
      .subscribe((epicList: Epic[]) => {
        this.epicList = epicList;
      });

    this.componentMessenger.epicTitleUpdated$
      .pipe(takeUntil(this.unsubscribe$))
      .subscribe((epicTitle: string) => { 
        this.epicTitle = epicTitle;
      });

    this.componentMessenger.epicNumberUpdated$
      .pipe(takeUntil(this.unsubscribe$))
      .subscribe((epicNumber: string) => {
        this.epicNumber = epicNumber;
      });
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-06
    • 2019-05-16
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    相关资源
    最近更新 更多