ngOnInit(): void {
// convert the `keyup` event into an observable stream
Observable.fromEvent(this.el.nativeElement, 'keyup')
.map((e: any) => e.target.value) // extract the value of the input
.filter((text: string) => text.length > 1) // filter out if empty
.debounceTime(250) // only once every 250ms
.do(() => this.loading.emit(true)) // enable loading
// search, discarding old events if new input comes in
.map((query: string) => this.youtube.search(query))
.switch()
// act on the return of the search
.subscribe(
(results: SearchResult[]) => { // on sucesss
this.loading.emit(false);
this.results.emit(results);
},
(err: any) => { // on error
console.log(err);
this.loading.emit(false);
},
() => { // on completion
this.loading.emit(false);
}
);
}
据我所知,第一次检测更改后便调用ngOnInit()。我的问题是Observable.fromEvent创建一个Observable流。这是否意味着在触发“ keyup”事件时使用相同的流?如果是这样,map()实际上会迭代该流中的每个值?我先输入a然后输入b,所以流中有2个值?一个是另一个是a,b?这就是为什么使用switch方法仅返回最新值的原因?
答案 0 :(得分:2)
据我所知,第一次检测更改后便调用ngOnInit()。
首次收到输入属性。这是从父组件中的更改检测周期开始的。
我的问题是Observable.fromEvent创建一个Observable流。这是否意味着在触发“ keyup”事件时使用相同的流?如果是这样,map()实际上会迭代该流中的每个值?我先输入a然后输入b,所以流中有2个值?一个是另一个是a,b?
是的,所有keyup
事件都依次流传输到该单个可观察事件。
这就是为什么使用switch方法仅返回最新值的原因?
流式传输新值后,switch
用于取消示例代码中对youtube.search(query)
的所有未决调用。
Observable.fromEvent(this.el.nativeElement, 'keyup')
我不喜欢这种方法,因为this.el
当时可能不可用,或者可以在组件的生命周期中重新创建。通过这种方法,您可以从创建的第一个元素中获取事件,这些事件可能会起作用,然后突然停止工作。
相反,我将模板上的keyup
事件和next()
绑定到主题。
<input type="text" (keyup)="onKeyup($event)">
import {Subject} from 'rxjs';
...
keyupSubject = new Subject();
endEvent = new Subject();
ngOnInit(): void {
this.keyupSubject
.map()
.filter()
.debounceTime()
.takeUntil(this.endEvent) // automatically unsubscribe when component is destroyed
.subscribe(() => {
...
});
}
ngOnDestroy() {
this.endEvent.next();
}
onKeyup(event) {
this.keyupSubject.next(event);
}
答案 1 :(得分:0)
ngOnInit()一次。
每次角度检测到变化时都会调用ngOnChange()。
尝试使用ngOnChange()而不是ngOnInit()