首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用单选按钮过滤Angular2过滤器/管道

使用单选按钮过滤Angular2过滤器/管道
EN

Stack Overflow用户
提问于 2017-07-03 04:05:08
回答 2查看 2.9K关注 0票数 1

我正在寻找一个过滤解决方案,它将实时过滤一组重复的元素。我在答案here中找到了一个基本的管道解决方案。

我发现<input [(ngModel)]='query'/>只有在同一个组件中才能工作。

但是-我需要从另一个组件中预先填充的单选按钮中获得筛选值。

到目前为止这是我的密码。

filter.component

代码语言:javascript
复制
<div class="topic" *ngFor="let topic of topics">
  {{topic.term}}
  <input [(ngModel)]="query" type="radio" name="topicFilter" [value]="topic.term"/>
</div>

grid.component

代码语言:javascript
复制
<router-outlet></router-outlet> // this pulls in the filter.component

<input [(ngModel)]="query"> // this is a text input that works as wanted ( for showing what I'm wanting to achieve )

<grid-item *ngFor="let user of users | topicFilterPipe: 'topic':query">
  <a [routerLink]="['user-story', user.uid]">
    <h1>{{user.fname}}</h1>
  </a>
  {{user.topic}}
</grid-item>

filter.pipe

代码语言:javascript
复制
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'topicFilterPipe'
})
export class TopicFilterPipePipe implements PipeTransform {

  public transform(value: Array<any>, keys: string, term: string) {
    console.log('pipe has run');
    if (!term) return value;
    return (value || []).filter((item) => keys.split(',').some(key => item.hasOwnProperty(key) && new RegExp(term, 'gi').test(item[key])));

  }

}

基本上--尝试实现与文本输入相同的方法,但是使用filter.component中所选的收音机。但是,我很难将所选的值传递到管道中&然后使用ngModel进行筛选。谢谢!

注意:我是angular2的新手+过滤器组件必须保持在单独的组件中

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-03 04:26:46

您的问题在于组件之间的通信。FilterComponent需要通知GridComponent一个新的查询被更新了。

因为服务是角度上的单例(存在异常,但这里不相关),如果我们从一个组件设置服务中的数据,其他组件可以访问数据。我们通过使用BehaviorSubject存储信息来使用观察者模式。

QueryService:

此服务将具有查询数据。getQuery将给出一个可观察的,可以被任何组件听到的。

代码语言:javascript
复制
@Injectable()
export class QueryService{

    public query = new BehaviorSubject<string>('');

    public getQuery(){
        return query;
    }

    public setQuery(queryStr){
        this.query.next(queryStr);
    }
}

FilterComponent

当值发生变化时,FilterComponent将调用该服务并进行更新。

HTML

代码语言:javascript
复制
<input 
    [ngModel]="query"
    (ngModelChange)="updateQuery($event)" 
    type="radio"
    name="topicFilter" [value]="topic.term"/>

TS

代码语言:javascript
复制
constructor(private queryService: QueryService){}
public updateQuery(query){
    queryService.setQuery(query);
}

GridComponent

代码语言:javascript
复制
public query:string; 

constructor(private queryService: QueryService){}

ngOnInit(){
  // .... other code
  queryService.getQuery()
     .subscribe(queryVal => {
          this.query = queryVal;
     });

}

您可以使用角事件机制并触发事件,这样gridcomponent就可以捕获事件并获得新的查询。但服务方式更好。由于路由器中有FilterComponent,这里很难使用事件机制。

在任何一种情况下,您都可以使用在您的问题中提到的管道。

代码语言:javascript
复制
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'topicFilterPipe'
})
export class TopicFilterPipePipe implements PipeTransform {

  public transform(value: Array<any>, keys: string, term: string) {
    console.log('pipe has run');
    if (!term) return value;
    return (value || []).filter((item) => keys.split(',').some(key => item.hasOwnProperty(key) && new RegExp(term, 'gi').test(item[key])));

  }

}

您可以使用问题中提到的管道,也可以直接在组件中筛选列表。

如果你仍然有问题,创建一个plnkr,我可以用这个答案来更新它。

票数 1
EN

Stack Overflow用户

发布于 2017-07-03 23:13:27

您可以使用这样的方法构建一个服务:

代码语言:javascript
复制
performFilter(filterBy: string): IProduct[] {
    filterBy = filterBy.toLocaleLowerCase();
    return this.products.filter((product: IProduct) =>
          product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1);
}

这是过滤产品清单..。但是你可以定制它来过滤你需要的东西。因为这需要在一个服务中,这样它才能被共享,所以您很可能需要传递要过滤的列表。所以更像这样:

代码语言:javascript
复制
performFilter(products: IProduct[], filterBy: string): IProduct[] {
    filterBy = filterBy.toLocaleLowerCase();
    return products.filter((product: IProduct) =>
          product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44877635

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档