如何过滤 Observable onKeyUp?

How can I filter an Observable onKeyUp?

如何搜索/过滤字符串数组类型的可观察对象?

例如,我有以下 observable

names$ = Observable.of(['Lenovo','Dell','Toshiba','Apple','Microsoft']);

现在我想根据用户在输入文本框中输入的内容来过滤这个可观察对象。

所以我有以下代码&我想return根据用户在输入框中输入的搜索词过滤观察值。

请注意,我正在寻找客户端解决方案。我的数据已经在客户端并且由于某种原因我无法在服务器上发送搜索词来过滤数据。我也明白,在这个例子中我可以直接在数组本身上使用过滤器,但我想通过 observable 来做到这一点。

我也试过 flatmap 运算符来展平数组,但仍然无法 return observable 最后应该是字符串数组类型。

任何帮助将不胜感激。提前致谢。

App.component.html

<!-- Textbox to receive user input -->
Search:<input type='text' [(ngModel)]='searchTerm' (keypress)='onkeypress($event.target.value)'>
<p>Search Term: {{searchTerm}}</p>
<hr>

<!-- Show search results here as ordered list -->
<ng-container *ngIf='(names$|async)?.length>0'>
    <ol>
        <li *ngFor='let name of names$|async'>
            {{name}}
        </li>
    </ol>
</ng-container>

App.component.ts

import {Component, OnInit} from '@angular/core';
import {Observable} from 'rxjs';

@Component({
    selector: 'my-app',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
    names$: Observable<string[]>;
    filteredNames$: Observable<string[]>;
    searchTerm: string;

    ngOnInit() {
        this.names$ = Observable.of(['Lenovo', 'Dell', 'Toshiba', 'Apple', 'Microsoft']);
    }

    // HOW TO IMPLEMENT THIS FUNCTION ??
    onkeypress(value) {
        console.log(value);
        this.names$ = this.names$.map(names => names.indexOf(value) > 0)
        // .filter(x=>{console.log(x.indexOf(value));return x.indexOf(value)>0})
        //     .subscribe(
        // (data)=>console.log(data),      (error)=>console.log('Error'+error),
        //       ()=>console.log('complete'));
    }
}

试试这个

let value='Del'
 Rx.Observable.from(['Lenovo','Dell','Toshiba','Apple','Microsoft'])
 .filter(name=>name.indexOf(value)!==-1)
 .subscribe(console.log);

你在这里犯了一些错误。

  1. 为什么要将 observable 映射到 names.indexOf(value) > 0.map() 从字面上转换可观察对象,您刚刚将类型为 string 的可观察对象转换为类型 boolean.

  2. 如果您希望 names 的列表在用户键入 (onkeyup) 时发生变化,为什么要将 this.names$ 重新分配回 this.names$ 再次?这将使您的代码工作一次,也就是仅在第一次击键时工作。您应该有两个变量,一个用于保存值,另一个用于绑定到您的 ngModel.

  3. 如果你想使用 async 管道,你不需要在你的 typescript 文件中订阅 observable。

在您的 ngOnInit() 中,创建一个变量来跟踪您的姓名:

ngOnInit() {
    this.data$ = Observable.of(['Lenovo', 'Dell', 'Toshiba', 'Apple', 'Microsoft']);
    this.names$ = this.data$;
}

假设您正在使用 async 管道,这应该是您的 onKeyUp 函数:

onKeyUp(value) {
    this.names$ = this.data$
        .map(x => {
             return x.filter(y=>y.toLowerCase().indexOf(value.toLowerCase())>-1);
        })
}

工作 Stackblit:https://stackblitz.com/edit/angular-yeaer6