过滤 table 多列数据 Angular 10
Filtering table data for multiple columns Angular 10
我需要根据我在 keyup
事件的输入中设置的值过滤 table 数据。由于有多个列,过滤后的数据应该相应显示。
在我的html下面有
<tr>
<td *ngFor="let t of tableHeader">
<input type="text" [id]="t.key" (keyup)="inputChange($event)">
</td>
</tr>
我的TS文件如下
public inputChange(value) {
var prevData = this.dataSource;
if (this.selectedId == '') {
prevData = this.result;
}
else if (this.selectedId != '' && this.selectedId != value.target.id) {
prevData = this.result;
}
if (this.selectedId != '' && filterValue.target.value == '') {
this.result = prevData;
return;
}
this.selectedId = value.target.id;
this.inputValue = value.target.value;
var filteredData = this.result.filter(x => x[this.selectedId] && x[this.selectedId].toString().toLowerCase().includes(this.inputValue.toLowerCase()));
this.result = filteredData;
}
到目前为止,我已经完成了此操作并相应地过滤了数据,但是当我从特定过滤器输入中删除一个值时,它会加载数据源。
预期:显示之前筛选的数据而不是数据源。
为了实现这一点,我将使用以下步骤使用 rxjs
- 将
datasource
定义为 Observable
dataSource = [
{
firstname: "James",
lastname: "Amstrong",
othernames: "Angel",
age: 35
},
{
firstname: "John",
lastname: "Peter",
othernames: "Ava",
age: 43
},
...
]
我们将使用 'rxjs'
中的 of
将此 datasource
转换为可观察对象
- 将过滤器定义为
Observable
tableHeader = [
{
key: "firstname"
},
{
key: "lastname"
},
...
];
filterKeyValues = this.tableHeader.map(({ key }) => ({ key, value: "" }));
filterSubject$ = new BehaviorSubject(this.filterKeyValues)
filter$ = this.filterSubject$.asObservable()
这只是生成一个 Observable
结构
Observable<[{ key: firtname, value: ''}, { key: lastname, value: ''}, ...]>
- 将两者合并return一个新的
Observable
作为新过滤的数据
dataSource$ = combineLatest([
this.filter$, of(this.dataSource)
]).pipe(
map(([filter, dataSource]) =>
dataSource.filter(item =>
filter.every((value) =>
(new RegExp(String(value.value).toLowerCase())).test(String(item[value.key]).toLowerCase())
)
)
)
)
- 为
inputChange
定义处理程序
public inputChange(event: any, key) {
this.filterKeyValues.find(({key: testKey}) => testKey === key).value = event.target.value
this.filterSubject$.next(this.filterKeyValues)
}
- 使用
async
显示内容
<table>
<tr>
<td *ngFor="let t of tableHeader">
<input type="text" [id]="t.key" (keyup)="inputChange($event, t.key)">
</td>
</tr>
<tr *ngFor="let item of dataSource$ | async">
<td>{{ item.firstname }}</td>
<td>{{ item.lastname }}</td>
<td>{{ item.othernames }}</td>
<td>{{ item.age }}</td>
</tr>
</table>
我们正在调用下一个值。这将强制进行更改检测,并且 datasorce$
Observable
将被重新评估,从而导致 UI
中的更新
我做了一个Demo Here来说明这个方法
我需要根据我在 keyup
事件的输入中设置的值过滤 table 数据。由于有多个列,过滤后的数据应该相应显示。
在我的html下面有
<tr>
<td *ngFor="let t of tableHeader">
<input type="text" [id]="t.key" (keyup)="inputChange($event)">
</td>
</tr>
我的TS文件如下
public inputChange(value) {
var prevData = this.dataSource;
if (this.selectedId == '') {
prevData = this.result;
}
else if (this.selectedId != '' && this.selectedId != value.target.id) {
prevData = this.result;
}
if (this.selectedId != '' && filterValue.target.value == '') {
this.result = prevData;
return;
}
this.selectedId = value.target.id;
this.inputValue = value.target.value;
var filteredData = this.result.filter(x => x[this.selectedId] && x[this.selectedId].toString().toLowerCase().includes(this.inputValue.toLowerCase()));
this.result = filteredData;
}
到目前为止,我已经完成了此操作并相应地过滤了数据,但是当我从特定过滤器输入中删除一个值时,它会加载数据源。
预期:显示之前筛选的数据而不是数据源。
为了实现这一点,我将使用以下步骤使用 rxjs
- 将
datasource
定义为Observable
dataSource = [
{
firstname: "James",
lastname: "Amstrong",
othernames: "Angel",
age: 35
},
{
firstname: "John",
lastname: "Peter",
othernames: "Ava",
age: 43
},
...
]
我们将使用 'rxjs'
of
将此 datasource
转换为可观察对象
- 将过滤器定义为
Observable
tableHeader = [
{
key: "firstname"
},
{
key: "lastname"
},
...
];
filterKeyValues = this.tableHeader.map(({ key }) => ({ key, value: "" }));
filterSubject$ = new BehaviorSubject(this.filterKeyValues)
filter$ = this.filterSubject$.asObservable()
这只是生成一个 Observable
结构
Observable<[{ key: firtname, value: ''}, { key: lastname, value: ''}, ...]>
- 将两者合并return一个新的
Observable
作为新过滤的数据
dataSource$ = combineLatest([
this.filter$, of(this.dataSource)
]).pipe(
map(([filter, dataSource]) =>
dataSource.filter(item =>
filter.every((value) =>
(new RegExp(String(value.value).toLowerCase())).test(String(item[value.key]).toLowerCase())
)
)
)
)
- 为
inputChange
定义处理程序
public inputChange(event: any, key) {
this.filterKeyValues.find(({key: testKey}) => testKey === key).value = event.target.value
this.filterSubject$.next(this.filterKeyValues)
}
- 使用
async
显示内容
<table>
<tr>
<td *ngFor="let t of tableHeader">
<input type="text" [id]="t.key" (keyup)="inputChange($event, t.key)">
</td>
</tr>
<tr *ngFor="let item of dataSource$ | async">
<td>{{ item.firstname }}</td>
<td>{{ item.lastname }}</td>
<td>{{ item.othernames }}</td>
<td>{{ item.age }}</td>
</tr>
</table>
我们正在调用下一个值。这将强制进行更改检测,并且 datasorce$
Observable
将被重新评估,从而导致 UI
我做了一个Demo Here来说明这个方法