如何过滤Observable onKeyUp?

时间:2017-12-12 04:26:44

标签: angular rxjs observable rxjs5 flatmap

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

例如,我有以下可观察的

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

现在我想根据输入文本框中的用户类型过滤此observable。

所以我有以下代码&我想根据用户在输入框中输入的searchTerm返回过滤后的observable。

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

我还尝试使用flatmap运算符来展平数组,但仍然无法返回最终应该是字符串数组类型的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'));
    }
}

2 个答案:

答案 0 :(得分:1)

试试这个

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

答案 1 :(得分:1)

你在这里犯了一些错误。

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

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

  3. 如果您想使用async管道,则无需在打字稿文件中订阅observable。

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

    使用Stackblits:https://stackblitz.com/edit/angular-yeaer6