Angular - 从click事件手动更新observable

时间:2017-07-24 04:14:58

标签: angular mouseevent observable

我正在进行预先输入以在输入搜索框时显示结果。基本上,我使用Observable.fromEvent来监听密钥事件并相应地向服务器发出请求。

点击其中一个结果后,它将

  1. 将用户带到详细信息页面
  2. 隐藏搜索结果
  3. 将当前搜索字词保留在搜索框内。
  4. 目前,我只会在用户点击回搜索框时显示上一个搜索结果,而且此信息可能已经过时。

    我想要存档的是每次点击文本框时,它会手动触发observable如果输入不为空。找到一些答案建议使用主题,但不知道如何在我的情况下应用它。请指教。

    @Component({
        selector: '[typeahead]',
        templateUrl: 'typeahead.directive.html',
        host: {        
            '(focus)':'onFocus($event)'
        }
    })
    export class TypeAheadComponent implements OnInit, OnDestroy {    
    
        ngOnInit() {
            this.subscriptions = [            
                this.listenAndSuggest()
            ];        
        }
    
        listenAndSuggest() {
            return Observable.fromEvent(this.element.nativeElement, 'keyup')
                .filter(this.validateKeyCode)
                .map((e: any) => e.target.value)
                .debounceTime(400)
                .concat()
                .distinctUntilChanged()
                .do(() => {
                    this.suggestionIndex = 0;
                    this.typeaheadSelecting.emit(true)
                })
                .filter((query: string) => {
                    if (!query) this.hideSuggestions()
                    return query.length > 0
                })
                .switchMap((query: string) => this.suggest(query))
                .catch((err) => {
                    this.typeaheadSelecting.emit(false);
                    return Observable.empty();
                })
                .subscribe((results: model.Task[]) => {
                    this.results = results;
                    this.typeaheadSelecting.emit(false);
                    this.showSuggestions = true
                });
        }
    
        onFocus(event) {
            let value = event.currentTarget.value;        
            if (!value)
                return;
            //to trigger the search again
        }
    }
    

1 个答案:

答案 0 :(得分:2)

每次调用Subject时,都会使用onFocus发出信号:

export class TypeAheadComponent implements OnInit, OnDestroy {

    // Remember to import subject from rxjs
    private onFocus$ = new Subject();

    ngOnInit() {
        this.subscriptions = [            
            this.listenAndSuggest()
        ];        
    }

    listenAndSuggest() {
        return Observable.fromEvent(this.element.nativeElement, 'keyup')
            .filter(this.validateKeyCode)
            .map((e: any) => e.target.value)
            .debounceTime(400)
            .concat()
            .distinctUntilChanged()
            .merge(onFocus$) // merge the values emitted by onFocus$ with the keyup values
            .do(() => {
                this.suggestionIndex = 0;
                this.typeaheadSelecting.emit(true)
            })
            .filter((query: string) => {
                if (!query) this.hideSuggestions()
                return query.length > 0
            })
            .switchMap((query: string) => this.suggest(query))
            .catch((err) => {
                this.typeaheadSelecting.emit(false);
                return Observable.empty();
            })
            .subscribe((results: model.Task[]) => {
                this.results = results;
                this.typeaheadSelecting.emit(false);
                this.showSuggestions = true
            });
    }

    onFocus(event) {
        let value = event.currentTarget.value;        
        if (!value)
            return;
        onfocus$.next(value); // emit value every time onFocus is called
    }
}