Angular材料表具有过滤器方法的数据源



在本教程的帮助下,我为角材料表编写了自己的数据源。我从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')
      );
  }
}

感谢您的帮助。

最好的问候。

相关内容

最新更新