2017-09-27 49 views
0

使用* A视图列表中的条目ngFor基于可观察到:* ng对可观测值的迭代。应该可以过滤onInput。怎么样?

view.html

<ion-searchbar [(ngModel)]="filter" (ionInput)="filterMeds()"></ion-searchbar> 
<ion-list> 
    <ion-item *ngFor="let medicine of getMeds$() | async"> 
     {{medicine.name}} 
    </ion-item> 
</ion-list> 

组件只是中继经由getMeds $可观察到的()函数:

component.ts

private _refreshOnInput$: Subject<any> = new Subject(); 


getMeds$(){ 
    return this.medsService.medsArray$; 
} 

Th e服务本身只是将数组作为可观察值返回:Observable<Medicine[]>

医学是由几个字符串组成的普通对象。

现在,我的问题:view.html添加了一个搜索栏。每当用户修改搜索条件,该filterMeds()函数被调用:

filterMeds(){ 
    this._refreshOnInput$.next(true); 
} 

这之后的blog post(CMD-F文本“刷新按钮”,看看有什么我想要实现的)。

我知道我的* ngFor必须迭代一个observable,它在应用一些过滤之后合并原始的this.medsService.medsArray$_refreshOnInput()

** component.ts尝试**

filteredMeds$: Observable<Medicine[]> 

// Constructor 

// An event is fired whenever the search input's updated 
filteredMeds$ = this._refreshOnInput$.map(() => 
    this.medsService.medsArray$ 
    .map(meds => 
     meds.filter(med => 
     med.name.toLowerCase().indexOf(this.filter.toLowerCase()) > -1 
    ) 
    ) 
); 

this.meds$ = Observable.merge(this.medsService.medsArray$, filteredMeds$); 

// Updating the getMeds$() method: 
getMeds$(){ 
    return this.medsService.medsArray$; 
} 

我无法弄清楚如何建立有效的滤波流。同样的错误发生时,我直接服务于filteredMeds $观察的到* ngFor:

ERROR Error: Error trying to diff '[object Object]'. Only arrays and iterables are allowed 

回答

0

也许这不是最好的解决方案,但它的工作原理。所以,请评论这种方法:

private _refreshMeds: Subject<any> = new Subject(); 
    meds$: Observable<any>; 
    filter: string = ''; 

    constructor(@Inject(MedsService) private medsService: MedsService) { 

    let filtered$ = new Observable(obs => { 
     this._refreshMeds.subscribe(() => 
     this.medsService.medsArray$.first().subscribe(medsArray => { 

      const filteredMeds = medsArray.filter(med => 
      (this.filter.length === 0) || 
      (med.name.toLowerCase().indexOf(this.filter.toLowerCase()) > -1)); 
      obs.next(filteredMeds); 
     }) 
    ) 
    }); 

    // Merging both the unfiltered (ie. at page load) or the filtered version 
    this.meds$ = Observable.merge(this.medsService.medsArray$, filtered$); 
    } 

    // Called by the input's changed listener (ionic: ionInput) 
    filterMeds(){ 
    this._refreshMeds.next(true); 
    } 
1

我猜你应该(getMeds$() | async)这样循环:因为在你的榜样

<ion-item *ngFor="let medicine of (getMeds$() | async)"> 

,您使用异步管对象,无结果getMeds $方法。


但更好的方法是使用公共参考medsService(在成分)和你的ngFor循环应该看起来像这样:

<ion-item *ngFor="let medicine of (medsService.medsArray$ | async)"> 

,因为你不应该使用HTML方式(以ngFor循环或ngIf条件的参数)。在您的情况下,视图中的每个更改都将被称为getMeds $()方法,对于Observables来说这完全是不必要的。

+0

嗨Jaroslaw,感谢您的输入,但我忘了提及基本未经过滤的observable显示正常。这个问题来自我的过滤。但是,感谢您的最佳做法提示! – Jem