typescript 如何从字符串输入中使用主题和去抖动 RxJs 5

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34520598/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:11:12  来源:igfitidea点击:

How to use subject and debounce with RxJs 5 from a string input

typescriptangularrxjs

提问by Mica?l Félix

I do not get how the Subject object would work for a Suggestion/Search servicethat I'm trying to implement in Angular2.

我不明白主题对象如何为我试图在 Angular2 中实现的建议/搜索服务工作。

Let's say that generateSuggestions gets called each time an input changes, for an autocomplete use.

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

I don't understand why I'm not able to get something out of the "next()" call, typescript compiler says it's returning a void type.

我不明白为什么我不能从“next()”调用中得到一些东西,打字稿编译器说它返回一个空类型。

My goal would be to submit each change to an object, which will decide to call each 500ms a function on the server, without spamming it on each key entry.

我的目标是将每个更改提交给一个对象,该对象将决定每 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) )
            );
    }
}

I can do this in plain JS/Typescript but I really wanted to try to work with RxJs because it's already used by Angular2.

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

What are the mistakes made here? The documentation is really poor without any example on their official website.

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

回答by Mica?l Félix

Note: if you have a better alternative, just post another answer and I will choose it as the answer.

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

My results have shown that I was not understanding well the purpose of Rx.Subject.

我的结果表明我没有很好地理解 Rx.Subject 的目的。



Suggested solution using ngModel and ngModelChange

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

Because I currently only use ngModel in my components, I had to split the [(ngModel)] to [ngModel] and (ngModelChange)

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

In the component constructor

在组件构造函数中

Use an Rx.Subject (theorically it's the same than an EventEmitter, but maybe it has changed since because we don't have access to all the Rx.Subject methods with it anymore) that will be parameterized to debounce and call the service to retrieve values.

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

For each keystroke:

对于每次击键:

Input -> (ngModelChange) -> eventEmitterComponentInstance.next(InputValue)

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

Code

代码

SuggestMultipleStringComponent.ts

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);
    }
}

SearchService.ts

搜索服务.ts

@Injectable()
export class SearchService {

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

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