【问题标题】:How to use subject and debounce with RxJs 5 from a string input如何使用 RxJs 5 从字符串输入中使用主题和去抖动
【发布时间】:2016-04-03 21:37:38
【问题描述】:

我不明白 Subject 对象如何用于我试图在 Angular2 中实现的建议/搜索服务

假设 每次输入更改都会调用 generateSuggestions,用于自动完成。

我不明白为什么我不能从“next()”调用中得到一些东西,打字稿编译器说它返回一个 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) )
            );
    }
}

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

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

【问题讨论】:

  • 您应该观看this video 了解如何进行预输入。
  • 我在看到那个视频后做了一些修改,rxJs 主题不再是服务的一部分。

标签: typescript angular rxjs


【解决方案1】:

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

我的结果表明我没有很好地理解 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
                .pipe(
                   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

@Injectable()
export class SearchService {
    
    constructor(private http: Http) {
        this.http = http;
    }
    
    callSomething() {
        return this.http.get('some/url')
                        .map((res: Response) => res.json());
    }
}

【讨论】:

  • 此语法不再有效,因为 Subject.debounceTime 在某个时候被删除了。
  • @spamguy 是的,现在它可能会通过管道 debounceTime(700) 工作。见rxjs.dev/api/operators/debounceTime我更新了我的答案。
猜你喜欢
  • 2021-09-08
  • 2019-01-21
  • 2016-07-17
  • 1970-01-01
  • 2020-07-22
  • 1970-01-01
  • 2017-09-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多