在本教程的帮助下,我为角材料表编写了自己的数据源。我从API中获取数据列表并将其显示在材料表中。
代码mydatasource
export class MyDataSource extends DataSource<any> {
private users: Observable<User[]>;
constructor(private userService: UserService) {
super();
}
connect(): Observable<User[]> {
this.users = this.userService.getAll();
return this.users;
}
disconnect() { }
filterWithCriteria(filterData: any): any {
return this.users
.filter(element => element[filterData.criteria].toLocaleLowerCase().includes(filterData.searchTerm.toLocaleLowerCase()))
.map(element => element)
.subscribe(
element => console.log(element),
err => console.error(err),
() => console.log('Streaming is over')
);
}
}
API提供可观察到的用户对象。
代码用户
export class User implements models.User {
constructor(
public name?: string,
public adress?: string,
public email?: string,
public telefon?: string,
public birthday?: Date
) {}
}
目的是在用户列表中搜索标准。标准可以是名称,地址,...
.filter(element => element[filterData.criteria].toLocaleLowerCase().includes(filterData.searchTerm.toLocaleLowerCase()))
这一行给了我错误
console.log(this.users[filterData.criteria]);
给我"未定义"。
感谢您的帮助,
最好的问候
您的示例中有两个错误:
1/似乎您的userService.getall((返回可观察到的可观察到的用户数组。
因此,当您返回this.users.filter时(元素...元素是用户的数组,而不是用户
那么良好的过滤链应为
filterWithCriteria(filterData: any): any {
return this.users
.map((users: User[] => {
return users.filter(user => {
return user[filterData.criteria].toLocaleLowerCase().includes(filterData.searchTerm.toLocaleLowerCase());
});
})
.subscribe(
users => console.log(users),
err => console.error(err),
() => console.log('Streaming is over')
);
}
2/数据源的连接应该是可观察到的要显示的用户。因此,连接方法需要返回可观察到的可观察的,该观察值将在更改过滤器(或更改用户列表(时发出新数据。我们缺乏有关如何实施过滤的信息,但以下是实现的示例
export class MyDataSource extends DataSource<User[]> {
private users: Observable<User[]>;
private filter$ = new BehaviorSubject({criteria: null, searchTerm: null});
/*
Every time your filter change you have to call
this.filter$.next({criteria: <theCriteria>, searchTerm: <theTerm>});
*/
constructor(private userService: UserService) {
super();
}
connect(): Observable<User[]> {
return Observable.combineLatest(this.userService.getAll(), this.filter$)
.map(latestValues => {
// every time filter$ or the observable from userService.getAll() emit a new data
const [users, filterData] = latestValues;
if (!filterData.criteria || !filterData.searchTerm) return users;
return users.filter(user => {
return user[filterData.criteria].toLocaleLowerCase().includes(filterData.searchTerm.toLocaleLowerCase());
});
});
}
disconnect() {}
}
注意:处理此操作的最佳方法可能是将您的过滤器$主题放在包装组件中,然后将其传递到数据源的构造函数中。
希望它有帮助!
@pierre mallet您的过滤器解决方案有效,但我真的不知道在哪里打电话
this.filter$.next({criteria: <theCriteria>, searchTerm: <theTerm>});
,由于选择了角材料,所以我进行了一些更改。
我的实际代码
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/filter';
import 'rxjs/add/observable/combineLatest';
import { DataSource } from '@angular/cdk/collections';
import { UserService } from '../shared/service/user.service';
import { User } from '../shared/user';
import { TransponderFormComponent } from '../transponder-form/transponder-form.component';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Component({
selector: 'app-transponder-list',
templateUrl: './transponder-list.component.html',
styleUrls: ['./transponder-list.component.scss']
})
export class TransponderListComponent implements OnInit {
public users: User[];
public displayedColumns = ['name', 'adress', 'city', 'email', 'telephon', 'birthday'];
public dataSource;
public selectedCriteria: String = '';
public searchCriteria = [
{ value: 'name', view: 'Name' },
{ value: 'city', view: 'City' },
{ value: 'adress', view: 'Adress' },
{ value: 'email', view: 'Email' },
{ value: 'telephon', view: 'Telephon' },
{ value: 'birthday', view: 'Birthday' }
];
constructor(private userService: UserService) { }
ngOnInit() {
this.dataSource = new MyDataSource(this.userService);
}
// get data from material select
public setSearchCriteria() { }
public filter(data: any) {
this.dataSource.filter(data.searchTerm, this.selectedColumn);
}
}
export class MyDataSource extends DataSource<any> {
private users: Observable<User[]>;
private filter$ = new BehaviorSubject({ criteria: null, searchTerm: null });
constructor(private userService: UserService) {
super();
}
connect(): Observable<User[]> {
this.users = this.userService.getAll();
return Observable.combineLatest(this.userService.getAll(), this.filter$)
.map(latestValues => {
const [users, filterData] = latestValues; // change
if (!filterData.criteria || !filterData.searchTerm) {
return users;
}
return users.filter(user => {
return user[filterData.criteria].toLocaleLowerCase().includes(filterData.searchTerm.toLocaleLowerCase());
});
});
}
disconnect() { }
filter(searchTerm: String, criteria: String) {
if (searchTerm !== '') {
// there is a tern to search
if ((criteria !== undefined) && (criteria !== '')) {
console.log('Search with term and criteria');
this.filterWithCriteria(searchTerm, criteria);
}
}
}
filterWithCriteria(searchTerm: String, criteria: any): any {
return this.users
.map((users: User[]) => {
return users.filter(user => {
return user[criteria].toLocaleLowerCase().includes(searchTerm.toLocaleLowerCase());
});
})
.subscribe(
users => console.log(users),
err => console.error(err),
() => console.log('Streaming is over')
);
}
}
感谢您的帮助。
最好的问候。