Angular 组件:我可以使用 Observable 而不是 EventEmitter 作为 @Output() 属性 吗?

Angular component: Can I use an Observable instead EventEmitter as @Output() property?

[angular2.4.5]

我试过了,它似乎像 EventEmitter 一样工作:

View this plunker

我喜欢这个,因为我的组件中没有订阅。

但这是实现这一目标的糟糕方法吗? risk/wrong 是什么?

使用 Subject 更好吗?

EventEmitter 只是扩展了 Subject,所以这并不奇怪(我也已经在 Dart 中看到了)。

他们使用自己的 class 以便以后能够在不破坏现有代码的情况下更改实现。

所以规避这种抽象可能不是最好的主意。如果你知道缺点并愿意接受它,你当然可以做到。

好吧,在您的情况下,您可以使用 EventEmitterSubject。您可以看到 EventEmitter 就像 Subject(尽管建议您尽可能使用 EventEmitter)。 https://github.com/angular/angular/blob/master/modules/%40angular/facade/src/async.ts

Observable.create(或new Observable())不适合这样使用。内部函数应该向观察者发出值和 return 一个拆卸函数(释放资源或其他)。不得保存为 属性.
但是,我不确定它可能会产生什么后果(内存泄漏?)。

所以宁愿使用 Subject 来代替:

export class SplitComponent implements OnDestroy {
  @Output() visibleTransitionEnd: Observable<string>
  visibleTransitionEndObserver: Subject;

  constructor() {
    const subject = new Subject();

    this.visibleTransitionEnd = subject.asObservable()
      .map(x => '> ' + x + ' <')
      .debounceTime(20)
      .do(() => console.log('here we are!'));
  }

  // ...
}

选择 EventEmitter 的 2 个理由

  1. Angular EventEmitter 可以确保在需要时异步传递事件。这有利于响应式用户体验。
  2. 封装下划线实现。如果有一天,Angular 的下一个版本将更新事件绑定,这取决于 EventEmitter 的新内容。如果 Subject 被广泛使用,那将是你项目的灾难。不确定这一点。但应避免。

Angular EventEmitter 扩展 RxJS Subject 目前只有 3 种方法:1) constructor(), 2) subscribe(next, error, complete) 和 3) 新方法 emit(value) {super.next(value);}

如果你new EventEmitter(true),它会异步传递事件

    constructor(isAsync = false) {
        super();
        this.__isAsync = isAsync;
    }

EventEmitter.subscribe() 根据 this._isAsync.

async 传递事件做了一些事情

我想指出使用 Observable 作为输出接口的一个优势是 你基本上可以投入任何你想要的观察

假设您有一个仅在表单有效并传递值时才会触发的事件。

使用事件发射器,您必须定义额外的 Emitter 实例来处理

@Output validValue = new EventEmitter()
this.form.valueChanges.pipe(tap(value=>{
if(ths.form.valid) 
   validValue.emit(value)
})).subscribbe()

使用 Observable 作为事件发射你可以简单地做到这一点

@Output() validValue=this.form.valueChanges.pipe(filter(_=>this.form.valid))