我正在寻找一种过滤解决方案,它将过滤一组重复的元素。我在答案here中找到了一个基本的管道解决方案。
我发现<input [(ngModel)]='query'/>
仅在同一组件内才有效。
但是 - 我需要让过滤器值来自另一个组件中预先填充的单选按钮。
到目前为止,这是我的代码。
filter.component
<div class="topic" *ngFor="let topic of topics">
{{topic.term}}
<input [(ngModel)]="query" type="radio" name="topicFilter" [value]="topic.term"/>
</div>
grid.component
<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
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 +非常新。过滤器组件必须保留在单独的组件中
答案 0 :(得分:1)
您的问题是关于组件之间的通信。 FilterComponent
需要通知GridComponent
新查询已更新。
由于Service是Angular中的单例(例外存在但不相关)如果我们从一个组件设置服务中的数据,则其他组件可以访问数据。我们使用BehaviorSubject来存储信息,从而使用Observer模式。
QueryService:
此服务将包含查询数据。 getQuery
将提供一个可由任何组件收听的可观察对象。
@Injectable()
export class QueryService{
public query = new BehaviorSubject<string>('');
public getQuery(){
return query;
}
public setQuery(queryStr){
this.query.next(queryStr);
}
}
<强> FilterComponent 强>
FilterComponent将调用服务并在值更改时更新。
HTML
<input
[ngModel]="query"
(ngModelChange)="updateQuery($event)"
type="radio"
name="topicFilter" [value]="topic.term"/>
TS
constructor(private queryService: QueryService){}
public updateQuery(query){
queryService.setQuery(query);
}
<强> GridComponent 强>
public query:string;
constructor(private queryService: QueryService){}
ngOnInit(){
// .... other code
queryService.getQuery()
.subscribe(queryVal => {
this.query = queryVal;
});
}
OR
您可以使用角度事件机制并触发事件,以便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])));
}
}
您可以使用问题中提到的管道,也可以直接在组件中自行过滤列表。
如果您仍有问题,请创建一个plnkr,我可以使用此答案为您更新。
答案 1 :(得分:0)
您可以使用以下方法构建服务:
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);
}