如何在异步管道上使用自定义管道?

时间:2017-01-09 12:24:45

标签: angular rxjs angular-pipe

我试图在异步管道上创建自定义管道,我尝试了很多解决方案,但仍然无法正常工作。这是代码片段。

product.sort.ts - 自定义管道

import { PipeTransform, Pipe } from '@angular/core';
import { Observable } from 'rxjs/Observable';

@Pipe({
    name: 'sortByName'
})
export class ProductPipe implements PipeTransform{
    /*transform(values: Array<any>, term:string){
        return values.filter(obj => obj.pname.startsWith(term))
    }*/

    //CODE NOT WORKING >>>>>
    transform($value: Observable<Array<any>>, term:string){
        if($value){
            $value.subscribe(
                (obj) => {
                    return obj.filter(obj => obj.pname.startsWith(term))
                }
            )
        }
    }
}

products.component.ts - 主要组件

import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { AppService } from '../app.service/app.service';
import { ProductPipe } from '../products.sort/products.sort';

@Component({
    selector: 'products-pg',
    template: `
        Products List:
        <ul>
            <li *ngFor = 'let product of $productList | async | sortByName:"A"'>{{product.pname}}</li>
        </ul>
    `
})
export class ProductsComponent implements OnInit{
    private $productList:Observable<Array<any>>;

    constructor(private _service: AppService, private _store: Store<Array<any>>){}

    ngOnInit(){
        this._service.setProductList();
        this.$productList = this._store.select('products');
    }
}

在这里,我使用商店进行状态管理,我试图按名称排序,所以通过&#34; A&#34;作为第一个字母。由于 $ productList 是可观察的,如何编写处理这样的异步行为的管道,请帮我解决这个问题。

3 个答案:

答案 0 :(得分:3)

最好的方法是仍然坚持你的异步,并在异步调用你的自定义管道之后,就像问题中的那个,只是你的管道代码现在将改变为不对要加载的数组起作用因为记录仍在加载,所以我们告诉我们的自定义管道不再做任何事情或返回空数组。 e.g

transform(items: any[], field: string, format?: string) { 
    if (items == null) //since the async is still working
      return [];
//do our normal pipe logic or function
    return items.sort((a: any, b: any) => {
      let value1 = a[field];
      let value2 = b[field];

      if (value1 > value2) {
        return 1;
      } else if (value1 < value2) {
        return -1;
      } else {
        return 0;
      }
    });

然后您的模板仍然保留

*ngFor = 'let product of $productList | async | sortByName:"A"'

答案 1 :(得分:2)

我有同样的问题以及我修复它的方式,就像这样:

<li class="list-group-item" *ngFor='let alert of _alerts$ | ipwrAlertFilter:seeAll | async'>

看看我在异步管道之前的自定义过滤器,这样我的自定义管道获得了一个可观察的,然后在我的管道中我有这个:

return value.map(data => data.filter(x => x.originalHasBeenSeen === false));

这样我的自定义管道仍会返回一些我仍然可以应用 async 管道的东西。所以对于流中的每个新项目,我仍然会在我的自定义管道上受到影响并且我的视图会更新。 希望这有帮助。

答案 2 :(得分:0)

如果每个人都不清楚,那就像......一样简单......

<div *ngFor="let product of (products$ | async | searchFilter: (query$ | async) )">

注意括号(query$ | async)已经在异步管道操作中。