在 Angular 中编写自定义 table 过滤器 6
Writing a custom table filter in Angular 6
我想在我的 angular 代码中添加自定义 table 过滤器。网络搜索并找到了这个博客 post:
https://www.code-sample.com/2018/07/angular-6-search-filter-pipe-table-by.html
它工作得很好,这里是管道代码:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'gridFilter'
})
/*
I got this code from here:
https://www.code-sample.com/2018/07/angular-6-search-filter-pipe-table-by.html
*/
export class GridFilterPipe implements PipeTransform {
transform(items: any, filter: any, defaultFilter: boolean): any {
if (!filter){
return items;
}
if (!Array.isArray(items)){
return items;
}
if (filter && Array.isArray(items)) {
let filterKeys = Object.keys(filter);
if (defaultFilter) {
return items.filter(item =>
filterKeys.reduce((x, keyName) =>
(x && new RegExp(filter[keyName], 'gi').test(item[keyName])) || filter[keyName] == "", true));
}
else {
return items.filter(item => {
return filterKeys.some((keyName) => {
return new RegExp(filter[keyName], 'gi').test(item[keyName]) || filter[keyName] == "";
});
});
}
}
}
}
除了这个 table 之外,它可以很好地满足我的大部分需求 html:
<div class="col-md-4" *ngIf="element == 'location'">
<div class="spacer"></div>
<div class="panel panel--vibblue panel--raised">{{ element | titlecase }}</div>
<div class="responsive-table panel--raised">
<table class="table table--bordered table--hover approvals-table" id="location-table">
<thead>
<tr>
<th class="sortable">{{ element | titlecase }} Name <span class="sort-indicator icon-chevron-down"></span></th>
<th class="sortable">Site <span class="sort-indicator icon-chevron-down"></span></th>
<th>Action</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let el of elements | gridFilter: {name: searchText, site:searchText}">
<tr>
<td>{{el.name}}</td>
<td>{{ getSiteName(el.site) }}</td>
<td>
<a><span class="icon-trash" (click)="deleteElement(el.id, el.name)"></span></a>
</td><td>
<a><span class="icon-pencil" (click)="editElement(el)"></span></a>
</td>
</tr>
</ng-container>
</tbody>
</table>
</div>
</div>
上面table的问题就是这个。要显示位置的站点名称,我使用此 html ...
<td>{{ getSiteName(el.site) }}</td>
... 它调用方法 getSiteName
,该方法采用站点的 id
和站点名称 returns。我不知道如何设置我的 gridFilter
。因此,如果我尝试搜索网站名称,我的 gridFilter 找不到该网站。
这是我的 stackblitz:https://stackblitz.com/edit/angular-damcul
** UPDATE **
我已经更新了我的 stackblitz to actually illustrate the problem I am having. Here is a screen shot of the stackblitz 应用程序:
我可以搜索位置,这是我搜索 'loc_2':
的屏幕截图
但是我无法搜索网站。这是我搜索任何 'site'.
的屏幕截图
进行了一些更改:
- 在问题的共享代码中,您使用了名为
grdFilter
的过滤器,在您的 stackblitz 中它是 'gridFilter'
- 添加了
getSiteName
的实现,它接收对象和 returns 博客名称(我们的数据中没有名为 'site' 的 属性)
- 在问题的共享代码中,您有
<ng-container *ngFor="let el of customerData | gridFilter: {name: searchText, site:searchText}">
- 由于我们的数据中没有名为'site'的属性,我们将其改为
<ng-container *ngFor="let el of customerData | grdFilter: {name: searchText, blog:searchText}">
相关hello.componenet.ts:
import { Component, Input } from '@angular/core';
@Component({
selector: 'hello',
template: `<input [(ngModel)]="searchText" placeholder="Search.." class="advancedSearchTextbox">
<p></p>
<table *ngFor="let emp of customerData | grdFilter: {name: searchText, Age:searchText, blog: searchText}; let i=index;">
<tr>
<td style="width: 5%;">{{i +1}}</td>
<td style="width: 10%;">{{emp.name}}</td>
<td style="width: 5%;">{{emp.Age}}</td>
<td style="width: 15%;">{{emp.blog}}</td>
</tr>
</table>
<hr/>
<table class="table table--bordered table--hover approvals-table" id="location-table">
<thead>
<tr>
<th class="sortable">{{ element | titlecase }} Name <span class="sort-indicator icon-chevron-down"></span></th>
<th class="sortable">Site <span class="sort-indicator icon-chevron-down"></span></th>
<th>Action</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let el of customerData | grdFilter: {name: searchText, blog:searchText}">
<tr>
<td>{{el.name}}</td>
<td>{{ getSiteName(el) }}</td>
<td>
<a><span class="icon-trash" (click)="deleteElement(el.id, el.name)"></span></a>
</td><td>
<a><span class="icon-pencil" (click)="editElement(el)"></span></a>
</td>
</tr>
</ng-container>
</tbody>
</table>
`,
styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent {
public searchText: string;
public customerData: any;
@Input() name: string;
constructor() { }
ngOnInit() {
this.customerData = [
{ "name": 'Anil kumar', "Age": 34, "blog": 'https://code-view.com' },
{ "name": 'Sunil Kumar Singh', "Age": 28, "blog": 'https://code-sample.xyz' },
{ "name": 'Sushil Singh', "Age": 24, "blog": 'https://code-sample.com' },
{ "name": 'Aradhya Singh', "Age": 5, "blog": 'https://code-sample.com' },
{ "name": 'Reena Singh', "Age": 28, "blog": 'https://code-sample.com' },
{ "name": 'Alok Singh', "Age": 35, "blog": 'https://code-sample.com' },
{ "name": 'Dilip Singh', "Age": 34, "blog": 'https://code-sample.com' }];
}
getSiteName(passedObj) {
return passedObj.blog;
}
}
update #1
in light of questioner's comment & updated question:
如果您转到 grd-pipe.ts 文件并执行 console.log(items,filter)
,您会看到我们在自定义管道内处理的数组是位置数组,它'sites' 列值为 1、2 或 3。您从站点数组中为 UI 获取的站点名称不是位置数组的一部分,因此管道无法处理.
因此,我们在存储站点名称的位置数组中创建一个新字段 siteName(来自 sites 数组),现在由于该字段在管道内可用,管道也可以在其上进行搜索。
TS
中的相关变化
ngOnInit(){
for(var i=0;i<this.locations.length;i++){
this.locations[i].siteName = this.sites.find(s => s.id === this.locations[i].site).name;
}
}
相关改动HTML添加字段siteName添加到过滤器:
<table class="table table--bordered table--hover approvals-table" id="location-table">
<tbody>
<ng-container *ngFor="let loc of locations | grdFilter: {name: searchText, siteName:searchText}; let i=index">
<tr>
<td style="width: 5%;">{{i +1}}</td>
<td style="width: 10%;">{{loc.name}}</td>
<td style="width: 5%;">{{getSiteName(loc.site)}}</td>
</tr>
</ng-container>
</tbody>
</table>
工作stackblitz here也更新了
我想在我的 angular 代码中添加自定义 table 过滤器。网络搜索并找到了这个博客 post:
https://www.code-sample.com/2018/07/angular-6-search-filter-pipe-table-by.html
它工作得很好,这里是管道代码:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'gridFilter'
})
/*
I got this code from here:
https://www.code-sample.com/2018/07/angular-6-search-filter-pipe-table-by.html
*/
export class GridFilterPipe implements PipeTransform {
transform(items: any, filter: any, defaultFilter: boolean): any {
if (!filter){
return items;
}
if (!Array.isArray(items)){
return items;
}
if (filter && Array.isArray(items)) {
let filterKeys = Object.keys(filter);
if (defaultFilter) {
return items.filter(item =>
filterKeys.reduce((x, keyName) =>
(x && new RegExp(filter[keyName], 'gi').test(item[keyName])) || filter[keyName] == "", true));
}
else {
return items.filter(item => {
return filterKeys.some((keyName) => {
return new RegExp(filter[keyName], 'gi').test(item[keyName]) || filter[keyName] == "";
});
});
}
}
}
}
除了这个 table 之外,它可以很好地满足我的大部分需求 html:
<div class="col-md-4" *ngIf="element == 'location'">
<div class="spacer"></div>
<div class="panel panel--vibblue panel--raised">{{ element | titlecase }}</div>
<div class="responsive-table panel--raised">
<table class="table table--bordered table--hover approvals-table" id="location-table">
<thead>
<tr>
<th class="sortable">{{ element | titlecase }} Name <span class="sort-indicator icon-chevron-down"></span></th>
<th class="sortable">Site <span class="sort-indicator icon-chevron-down"></span></th>
<th>Action</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let el of elements | gridFilter: {name: searchText, site:searchText}">
<tr>
<td>{{el.name}}</td>
<td>{{ getSiteName(el.site) }}</td>
<td>
<a><span class="icon-trash" (click)="deleteElement(el.id, el.name)"></span></a>
</td><td>
<a><span class="icon-pencil" (click)="editElement(el)"></span></a>
</td>
</tr>
</ng-container>
</tbody>
</table>
</div>
</div>
上面table的问题就是这个。要显示位置的站点名称,我使用此 html ...
<td>{{ getSiteName(el.site) }}</td>
... 它调用方法 getSiteName
,该方法采用站点的 id
和站点名称 returns。我不知道如何设置我的 gridFilter
。因此,如果我尝试搜索网站名称,我的 gridFilter 找不到该网站。
这是我的 stackblitz:https://stackblitz.com/edit/angular-damcul
** UPDATE **
我已经更新了我的 stackblitz to actually illustrate the problem I am having. Here is a screen shot of the stackblitz 应用程序:
我可以搜索位置,这是我搜索 'loc_2':
的屏幕截图但是我无法搜索网站。这是我搜索任何 'site'.
的屏幕截图进行了一些更改:
- 在问题的共享代码中,您使用了名为
grdFilter
的过滤器,在您的 stackblitz 中它是 'gridFilter' - 添加了
getSiteName
的实现,它接收对象和 returns 博客名称(我们的数据中没有名为 'site' 的 属性) - 在问题的共享代码中,您有
<ng-container *ngFor="let el of customerData | gridFilter: {name: searchText, site:searchText}">
- 由于我们的数据中没有名为'site'的属性,我们将其改为
<ng-container *ngFor="let el of customerData | grdFilter: {name: searchText, blog:searchText}">
相关hello.componenet.ts:
import { Component, Input } from '@angular/core';
@Component({
selector: 'hello',
template: `<input [(ngModel)]="searchText" placeholder="Search.." class="advancedSearchTextbox">
<p></p>
<table *ngFor="let emp of customerData | grdFilter: {name: searchText, Age:searchText, blog: searchText}; let i=index;">
<tr>
<td style="width: 5%;">{{i +1}}</td>
<td style="width: 10%;">{{emp.name}}</td>
<td style="width: 5%;">{{emp.Age}}</td>
<td style="width: 15%;">{{emp.blog}}</td>
</tr>
</table>
<hr/>
<table class="table table--bordered table--hover approvals-table" id="location-table">
<thead>
<tr>
<th class="sortable">{{ element | titlecase }} Name <span class="sort-indicator icon-chevron-down"></span></th>
<th class="sortable">Site <span class="sort-indicator icon-chevron-down"></span></th>
<th>Action</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let el of customerData | grdFilter: {name: searchText, blog:searchText}">
<tr>
<td>{{el.name}}</td>
<td>{{ getSiteName(el) }}</td>
<td>
<a><span class="icon-trash" (click)="deleteElement(el.id, el.name)"></span></a>
</td><td>
<a><span class="icon-pencil" (click)="editElement(el)"></span></a>
</td>
</tr>
</ng-container>
</tbody>
</table>
`,
styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent {
public searchText: string;
public customerData: any;
@Input() name: string;
constructor() { }
ngOnInit() {
this.customerData = [
{ "name": 'Anil kumar', "Age": 34, "blog": 'https://code-view.com' },
{ "name": 'Sunil Kumar Singh', "Age": 28, "blog": 'https://code-sample.xyz' },
{ "name": 'Sushil Singh', "Age": 24, "blog": 'https://code-sample.com' },
{ "name": 'Aradhya Singh', "Age": 5, "blog": 'https://code-sample.com' },
{ "name": 'Reena Singh', "Age": 28, "blog": 'https://code-sample.com' },
{ "name": 'Alok Singh', "Age": 35, "blog": 'https://code-sample.com' },
{ "name": 'Dilip Singh', "Age": 34, "blog": 'https://code-sample.com' }];
}
getSiteName(passedObj) {
return passedObj.blog;
}
}
update #1 in light of questioner's comment & updated question:
如果您转到 grd-pipe.ts 文件并执行 console.log(items,filter)
,您会看到我们在自定义管道内处理的数组是位置数组,它'sites' 列值为 1、2 或 3。您从站点数组中为 UI 获取的站点名称不是位置数组的一部分,因此管道无法处理.
因此,我们在存储站点名称的位置数组中创建一个新字段 siteName(来自 sites 数组),现在由于该字段在管道内可用,管道也可以在其上进行搜索。
TS
中的相关变化ngOnInit(){
for(var i=0;i<this.locations.length;i++){
this.locations[i].siteName = this.sites.find(s => s.id === this.locations[i].site).name;
}
}
相关改动HTML添加字段siteName添加到过滤器:
<table class="table table--bordered table--hover approvals-table" id="location-table">
<tbody>
<ng-container *ngFor="let loc of locations | grdFilter: {name: searchText, siteName:searchText}; let i=index">
<tr>
<td style="width: 5%;">{{i +1}}</td>
<td style="width: 10%;">{{loc.name}}</td>
<td style="width: 5%;">{{getSiteName(loc.site)}}</td>
</tr>
</ng-container>
</tbody>
</table>
工作stackblitz here也更新了