当用户停止输入时,Angular2 @ TypeScript错误rxjs / Subject :: filtering

时间:2016-02-22 16:30:55

标签: typescript angular rxjs

我使用的是Angular 2.0.0-beta.0和TypeScript 1.7.5。在尝试更改聪明的过滤器时:

https://angular.io/docs/ts/latest/guide/server-communication.html#!#more-observables

"聪明"过滤器应该只在用户停止输入时执行某些操作。

我收到编译错误:

Error:(30, 20) TS2345: Argument of type '(term: string) => void' is not assignable to parameter of type '(x: {}, ix: number) => Observable<any>'. Type 'void' is not assignable to type 'Observable<any>'.

运行时错误:

EXCEPTION: Error during instantiation of Test!.  
ORIGINAL EXCEPTION: TypeError: this._searchTermStream.debounceTime is not a function

test.ts

import {bootstrap} from 'angular2/platform/browser';
import {Component} from 'angular2/core';
import {Observable}        from 'rxjs/Observable';
import {Subject}           from 'rxjs/Subject';

@Component({
    selector: 'my-app',
    template: `
        <h3>Test</h3>
        Filter basic <input #filterBasic (keyup)="searchBasic(filterBasic.value)"/><br>
        Filter clever <input #filterClever (keyup)="searchClever(filterClever.value)"/>
        <ul>
            <li *ngFor="#contact of contactsFilter">{{contact}}</li>
        </ul>
    `
})

export class Test {

    public contacts: string[] = ["John", "Kaen", "Kath", "Joop", "Joost"];
    public contactsFilter: string[] = this.contacts;

    private _searchTermStream = new Subject<string>();

    private items:Observable<string[]> = this._searchTermStream
        .debounceTime(300)
        .distinctUntilChanged()
        .switchMap((term: string) => this.contactFilter(term));

    constructor () {}

    searchBasic(term: string) {
        console.log("Filter Basic " + term + " called");
        this.contactFilter(term);
    }

    searchClever(term: string) {
        console.log("Filter Clever " + term + " called");
        this._searchTermStream.next(term);
    }

    contactFilter(term: string) {
        this.contactsFilter = this.contacts.filter(item => (item.indexOf(term) >= 0))
    }
}

bootstrap(Test);

的index.html

<!DOCTYPE html>
<html>
  <head>
    <base href="/">
    <script src="angular2/bundles/angular2-polyfills.js"></script>
    <script src="typescript/lib/typescript.js"></script>
    <script src="systemjs/dist/system.js"></script>
    <script src="angular2/bundles/router.dev.js"></script>
    <script src="rxjs/bundles/Rx.js"></script>
    <script src="angular2/bundles/angular2.js"></script>
    <script src="angular2/bundles/http.dev.js"></script>
    <link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
    <script>
      System.config({
        transpiler: 'typescript',
        typescriptOptions: { emitDecoratorMetadata: true },
        packages: {'components': {defaultExtension: 'ts'}}
      });
      System.import('components/test')
            .then(null, console.error.bind(console));
    </script>
  </head>
  <body>
    <my-app>Loading...</my-app>
  </body>
</html>

2 个答案:

答案 0 :(得分:7)

您收到运行时错误,因为默认情况下Observables只有几个运算符。您必须明确导入它们:

// in test.ts
import 'rxjs/add/operator/debounceTime';

或:

// in bootstrap.ts
import 'rxjs/Rx';

编译错误是因为签名与docs中的签名不匹配。换几行:

.switchMap((term: any, i) => this.contactFilter(term));

contactFilter(term: string) {
    this.contactsFilter = this.contacts.filter(item => (item.indexOf(term) >= 0))
    // Return some observable to make editor happy
    // Could be something useful even (;
    // Or just like this:
    return Observable.of(true);
}

答案 1 :(得分:1)

关于运行时错误,您没有导入debounceTime运算符,如下所述:

Panel

默认情况下不包含运营商,您需要根据需要逐个添加。

更多详细信息请参阅此答案: