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

Angular2过滤器/管道使用单选按钮进行过滤,angular,Angular,我正在寻找一个过滤解决方案,将活过滤一组重复的元素。我在答案中找到了一个基本的管道解决方案 我发现,只有在同一个组件中才能工作 但是-我需要有来自另一个组件中预填充单选按钮的筛选值 这是到目前为止我的代码 过滤组件 <div class="topic" *ngFor="let topic of topics"> {{topic.term}} <input [(ngModel)]="query" type="radio" name="topicFilter" [value

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

我发现,
只有在同一个组件中才能工作

但是-我需要有来自另一个组件中预填充单选按钮的筛选值

这是到目前为止我的代码

过滤组件

<div class="topic" *ngFor="let topic of topics">
  {{topic.term}}
  <input [(ngModel)]="query" type="radio" name="topicFilter" [value]="topic.term"/>
</div>
<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>
public query:string; 

constructor(private queryService: QueryService){}

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

}

{{topic.term}
网格组件

<div class="topic" *ngFor="let topic of topics">
  {{topic.term}}
  <input [(ngModel)]="query" type="radio" name="topicFilter" [value]="topic.term"/>
</div>
<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>
public query:string; 

constructor(private queryService: QueryService){}

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

}
//这将引入filter.com组件
//这是一个文本输入,可以根据需要工作(用于显示我想要实现的目标)
{{user.fname}
{{user.topic}
过滤管道

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])));

  }

}
从'@angular/core'导入{Pipe,PipeTransform};
@烟斗({
名称:“topicFilterPipe”
})
导出类TopicFilterPipePipe实现PipeTransform{
公共转换(值:数组,键:字符串,术语:字符串){
console.log(“管道已运行”);
if(!term)返回值;
return(value | |[]).filter((item)=>keys.split(',')).some(key=>item.hasOwnProperty(key)和&newregexp(term,'gi').test(item[key]);
}
}
基本上-尝试实现与文本输入相同的方法,但使用
filter.component
中选定的收音机。但是,我正在努力将选定的值传递到管道中,然后使用ngModel进行过滤。谢谢大家!


注意:我对angular2+非常陌生,过滤器组件必须保留在单独的组件中

您的问题在于组件之间的通信
FilterComponent
需要通知
GridComponent
新查询已更新

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

查询服务:

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

@Injectable()
export class QueryService{

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

    public getQuery(){
        return query;
    }

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

<div class="topic" *ngFor="let topic of topics">
  {{topic.term}}
  <input [(ngModel)]="query" type="radio" name="topicFilter" [value]="topic.term"/>
</div>
<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>
public query:string; 

constructor(private queryService: QueryService){}

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

}

您可以使用angular事件机制并触发事件,以便gridcomponent可以捕获事件并获取新查询。但服务方式做得更好。因为在路由器中有FilterComponent,所以在这里很难使用事件机制

无论哪种情况,您都可以使用问题中提到的管道

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])));

  }

}
从'@angular/core'导入{Pipe,PipeTransform};
@烟斗({
名称:“topicFilterPipe”
})
导出类TopicFilterPipePipe实现PipeTransform{
公共转换(值:数组,键:字符串,术语:字符串){
console.log(“管道已运行”);
if(!term)返回值;
return(value | |[]).filter((item)=>keys.split(',')).some(key=>item.hasOwnProperty(key)和&newregexp(term,'gi').test(item[key]);
}
}
您可以使用问题中提到的管道,也可以直接在组件中过滤列表


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

您可以使用以下方法构建服务:

performFilter(filterBy: string): IProduct[] {
    filterBy = filterBy.toLocaleLowerCase();
    return this.products.filter((product: IProduct) =>
          product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1);
}
performFilter(products: IProduct[], filterBy: string): IProduct[] {
    filterBy = filterBy.toLocaleLowerCase();
    return products.filter((product: IProduct) =>
          product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1);
}
这是筛选产品列表。。。但是你可以定制它来过滤你需要的任何东西。由于这需要在服务中才能共享,因此您很可能需要传入要筛选的列表。更像这样:

performFilter(filterBy: string): IProduct[] {
    filterBy = filterBy.toLocaleLowerCase();
    return this.products.filter((product: IProduct) =>
          product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1);
}
performFilter(products: IProduct[], filterBy: string): IProduct[] {
    filterBy = filterBy.toLocaleLowerCase();
    return products.filter((product: IProduct) =>
          product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1);
}

对不起,我不能完全确定我是否听懂了。我对angular2很不熟悉。你能说清楚一点吗?当然,为什么不呢。我会在一小时后更新更详细的答案。我现在正在旅行。不幸的是,当我尝试实现此代码时出现错误?主要在您提供的query.service代码中。我遗漏了什么吗?错误是什么。您是否将import添加到“rxjs/BehaviorSubject”中的Behavior subjected
import{BehaviorSubject}但是我在类的第一行中得到一个错误
@Injectable()导出类QueryService{let query=new BehaviorSubject(“”);//let public getQuery()出错{//error here return query.toObservable();}public setQuery(queryStr){//error here this.query.next(queryStr);}
意外标记。应为构造函数、方法、访问器或属性。找不到名称“getQuery”。找不到名称“setQuery”。找不到名称“queryStr”。如果有多行数据,则通常不建议使用管道进行筛选。请看:您可以在组件本身中进行筛选。@DeborahK我至少有500行数据。所以你可能是对的。我将如何处理filter.component中的筛选并将其传递到grid.component下面的回答中查看我的回答。正如其他人在回答中提到的,服务是管理多个组件之间状态信息的好方法。这就是您实际正在做的,更改应用程序的状态。该服务还可以扩展到与其他过滤器进行信息通信,但其目的应保持一致。e、 例如,一个管理用户体验偏好的服务和另一个管理用户看到的广告流的服务。恐怕我不能完全确定如何在我的代码中实现这一点。由于我没有遵循您从API收集“产品”时使用的相同方法,因此我无法完全掌握如何在代码中实现它。我对Angulari非常熟悉,如果您可以使用一些示例代码构建plunker,我们可以提供更详细的示例。您可以使用Plunker使用以下链接构建示例Angular应用程序: