Angular 组件:我可以使用 Observable 而不是 EventEmitter 作为 @Output() 属性 吗?
Angular component: Can I use an Observable instead EventEmitter as @Output() property?
[angular2.4.5]
我试过了,它似乎像 EventEmitter 一样工作:
我的外部组件:
<split (visibleTransitionEnd)="log($event)"></split>
组件内部:
@Output() visibleTransitionEnd: Observable<string>
observer: Observer;
constructor() {
const myObs = new Observable(observer => this.observer = observer);
this.visibleTransitionEnd = myObs
.map(x => '> ' + x + ' <')
.debounceTime(20)
.do(() => console.log('here we are!'));
}
然后我可以在组件内部调用:
// needed condition because if nobody subscribe 'visibleTransitionEnd' > no observer!
if(this.observer) this.observer.next('test');
我喜欢这个,因为我的组件中没有订阅。
但这是实现这一目标的糟糕方法吗? risk/wrong 是什么?
使用 Subject
更好吗?
EventEmitter
只是扩展了 Subject
,所以这并不奇怪(我也已经在 Dart 中看到了)。
他们使用自己的 class 以便以后能够在不破坏现有代码的情况下更改实现。
所以规避这种抽象可能不是最好的主意。如果你知道缺点并愿意接受它,你当然可以做到。
好吧,在您的情况下,您可以使用 EventEmitter
或 Subject
。您可以看到 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 个理由
- Angular
EventEmitter
可以确保在需要时异步传递事件。这有利于响应式用户体验。
- 封装下划线实现。如果有一天,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))
[angular2.4.5]
我试过了,它似乎像 EventEmitter 一样工作:
我的外部组件:
<split (visibleTransitionEnd)="log($event)"></split>
组件内部:
@Output() visibleTransitionEnd: Observable<string> observer: Observer; constructor() { const myObs = new Observable(observer => this.observer = observer); this.visibleTransitionEnd = myObs .map(x => '> ' + x + ' <') .debounceTime(20) .do(() => console.log('here we are!')); }
然后我可以在组件内部调用:
// needed condition because if nobody subscribe 'visibleTransitionEnd' > no observer! if(this.observer) this.observer.next('test');
我喜欢这个,因为我的组件中没有订阅。
但这是实现这一目标的糟糕方法吗? risk/wrong 是什么?
使用 Subject
更好吗?
EventEmitter
只是扩展了 Subject
,所以这并不奇怪(我也已经在 Dart 中看到了)。
他们使用自己的 class 以便以后能够在不破坏现有代码的情况下更改实现。
所以规避这种抽象可能不是最好的主意。如果你知道缺点并愿意接受它,你当然可以做到。
好吧,在您的情况下,您可以使用 EventEmitter
或 Subject
。您可以看到 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 个理由
- Angular
EventEmitter
可以确保在需要时异步传递事件。这有利于响应式用户体验。 - 封装下划线实现。如果有一天,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
.
我想指出使用 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))