如何使用字符串输入中的RxJs 5进行主题和去抖动

Mic*_*lix 3 rxjs typescript angular

我不知道Subject对象如何用于我想在Angular2中实现的Suggestion/Search服务.

假设每次输入更改时都会调用generateSuggestions ,以供自动完成使用.

我不明白为什么我无法从"next()"调用中得到一些东西,typescript编译器说它返回了一个void类型.

我的目标是将每个更改提交给一个对象,该对象将决定在服务器上调用每个500毫秒的函数,而不会在每个密钥条目上发送垃圾邮件.

import { Jsonp, Response, Http } from 'angular2/http';
import * as Rx from 'rxjs/Rx';
import { Injectable } from 'angular2/core';

@Injectable()
export class SearchService {
    queryStream = new Rx.Subject();

    constructor(public http: Http) {

    }

    generateSuggestions(query: string) {
        this.queryStream
            .next(query)
            .debounce(500) // Compiler error: Debounce does not exist on type "void"
            .map(
                query => this.http.get('hellow')
                        .map( (res: Response) => res.json() )
                        .subscribe( results => console.log(results) )
            );
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以在普通的JS/Typescript中做到这一点,但我真的想尝试使用RxJ,因为它已经被Angular2使用了.

这里犯了什么错误?在他们的官方网站上没有任何示例的文档真的很差.

Mic*_*lix 10

注意:如果你有更好的选择,只需发布​​另一个答案,我会选择它作为答案.

我的结果表明我不太了解Rx.Subject的目的.


使用ngModel和ngModelChange建议的解决方案

因为我目前只在我的组件中使用ngModel,所以我不得不将[(ngModel)]拆分为[ngModel]和(ngModelChange)

在组件构造函数中

使用Rx.Subject(理论上它与EventEmitter相同,但可能因为我们无法再访问所有Rx.Subject方法而改变了),这些方法将参数化为去抖动并调用服务来检索值.

每次击键:

输入 - >(ngModelChange) - > eventEmitterComponentInstance.next(InputValue)

SuggestMultipleStringComponent.ts

@Component({
  template: `<input [ngModel]="userInput"
                    (ngModelChange)="userInputChanged($event)" />`
  providers: [SearchService]
})
export class SuggestMultipleStringComponent { 
    private typeAheadEventEmitter = new Rx.Subject<string>();
    private userInput: string;

    constructor(private _searchService: SearchService) {
        this.typeAheadEventEmitter
                .debounceTime(700)
                .switchMap(val => {
                    console.log('called once')
                    return this._searchService.callSomething();
                }).subscribe(results => {
                    console.log(results);
                }, error => {
                    console.log('error logged:');
                    console.log(error);
                });
      }

    userInputChanged(value: string) {
        this.userInput = value;
        this.typeAheadEventEmitter.next(value);
    }
}
Run Code Online (Sandbox Code Playgroud)

SearchService.ts

@Injectable()
export class SearchService {

    constructor(private http: Http) {
        this.http = http;
    }

    callSomething() {
        return this.http.get('some/url')
                        .map((res: Response) => res.json());
    }
}
Run Code Online (Sandbox Code Playgroud)