【问题标题】:Filtering specific column in Angular Material Table with filtering in angular?用角度过滤过滤角度材料表中的特定列?
【发布时间】:2018-10-01 01:45:01
【问题描述】:

我正在使用mat-table。它有一个可以正常工作的过滤器。

针对以下数据(所有列)进行过滤

const ELEMENT_DATA: Element[] = [
  {position: 14598, name: 'Hydrogen', weight: 1.0079, symbol: 'H'},
  {position: 24220, name: 'Helium', weight: 4.0026, symbol: 'He'},
  {position: 39635, name: 'Lithium', weight: 6.941, symbol: 'Li'},
  {position: 42027, name: 'Beryllium', weight: 9.0122, symbol: 'Be'},
  {position: 53216, name: 'Boron', weight: 10.811, symbol: 'B'},
  {position: 60987, name: 'Carbon', weight: 12.0107, symbol: 'C'},
  {position: 70976, name: 'Nitrogen', weight: 14.0067, symbol: 'N'},
  {position: 81297, name: 'Oxygen', weight: 15.9994, symbol: 'O'},
  {position: 90975, name: 'Fluorine', weight: 18.9984, symbol: 'F'},
  {position: 18879, name: 'Neon', weight: 20.1797, symbol: 'Ne'},
  {position: 11209, name: 'Sodium', weight: 22.9897, symbol: 'Na'}

];

但是现在我正在尝试更改过滤器,因为我想要的是过滤器仅用于 "position", "name", "symbol" 列。我已经完成了这个例子,但是Filtering specific column in Angular Material table in angular 5。

我不明白请帮我解决这个问题

StackBlitz Code

【问题讨论】:

    标签: angular angular-material2


    【解决方案1】:

    您必须覆盖数据源的filterPredicate。

    下面是一个例子:Working demo


    基本上,您想指定过滤器应用于数据中的哪些属性:

    this.dataSource.filterPredicate = function(data, filter: string): boolean {
        return data.name.toLowerCase().includes(filter) || data.symbol.toLowerCase().includes(filter) || data.position.toString().includes(filter);
    };
    

    【讨论】:

    • 澄清一下,如果一个元素的位置是11209,并且用户输入112,你想显示那个元素吗?
    • 如果一个元素的位置是11209,用户输入112是需要显示
    • 我们也可以有一个动态的包含语句,因为有时没有。显示的列数可能在 20-30 左右,就像我的情况一样
    【解决方案2】:

    在Angular Material Tables中,我们可以从数据本身创建基于列的过滤器。

    来源Link

    演示Link

    为此,我们需要用 customFilter() 方法覆盖 filterPredicate 方法

            ...
            ngOnInit() {
                this.getRemoteData();
    
                // Overrride default filter behaviour of Material Datatable
                this.dataSource.filterPredicate = this.createFilter();
            }
            ...
    
            // Custom filter method fot Angular Material Datatable
            createFilter() {
                let filterFunction = function (data: any, filter: string): boolean {
                let searchTerms = JSON.parse(filter);
                let isFilterSet = false;
                for (const col in searchTerms) {
                    if (searchTerms[col].toString() !== '') {
                    isFilterSet = true;
                    } else {
                    delete searchTerms[col];
                    }
                }
    
                let nameSearch = () => {
                    let found = false;
                    if (isFilterSet) {
                    for (const col in searchTerms) {
                        searchTerms[col].trim().toLowerCase().split(' ').forEach(word => {
                        if (data[col].toString().toLowerCase().indexOf(word) != -1 && isFilterSet) {
                            found = true
                        }
                        });
                    }
                    return found
                    } else {
                    return true;
                    }
                }
                return nameSearch()
                }
                return filterFunction
            }
    

    检查完整的工作代码here

    【讨论】:

      【解决方案3】:

      添加到错误的答案。这是一个更详细的实现,

      export class FilterTable implements AfterViewInit {
        //some datasource
        datasource //=
        displayedColumns //=insert column names on which you want to filter whether they are displayed or not, but present in the datasource
      
        // Apply filter to the datasource
        applyFilter(filterValue: string) {
          this.datasource.filter = filterValue;
        }
      
      
        ngAfterViewInit() {
          // Overwriting filterPredicate here, as it needs to be done after the datasource is loaded.
          this.datasource.filterPredicate = (data, filter) => {
            var tot = false;
            for (let column of this.displayedColumns) {
              //incase if there is a date type and is displayed differently using a pipe, then convert it intorequired format before filtering
              //check if all the columnson which you are filtering are actually present
              if ((column in data) && (new Date(data[column].toString()).toString() == "Invalid Date")) {
                //if not date column
                tot = (tot || data[column].toString().trim().toLowerCase().indexOf(filter.trim().toLowerCase()) !== -1);
              } else {
                //change this to the format in which date is displayed
                var date = new Date(data[column].toString());
                var m = date.toDateString().slice(4, 7) + " " + date.getDate() + " " + date.getFullYear();
                tot = (tot || m.toLowerCase().indexOf(filter.trim().toLowerCase()) !== -1);
              }
            }
            return tot;
          }
        }
      }
      

      如果可以改进,请随时提出修改建议

      【讨论】:

      • 你的代码没有编译:Uncaught SyntaxError: Unexpected token export
      • 我写了代码供参考。我已经进行了更改,请再次检查
      • { "message": "Uncaught SyntaxError: Unexpected token export", "filename": "stacksnippets.net/js", "lineno": 13, "colno": 9 }
      • 很抱歉这不是sn-p代码,它只是一个示例代码,因此您无法运行sn-p。我已经改变了它。谢谢
      【解决方案4】:

      Material 已经实现了自己的搜索功能,您可以通过更新日期源的 filterPredicate 属性来覆盖它。在 ngOninit() 生命周期中调用 generateTable 函数。

      generateTable(tableData: any) {
          this.dataSource = new MatTableDataSource(tableData);
          this.dataSource.paginator = this.paginator;
          this.dataSource.sort = this.sort;
          this.dataSource.filterPredicate = (data: any, filter: string) => {
            console.log(data);
            console.log(filter);
            let matchFound = false;
            for (let column of this.displayedColumns) {
              if(column in data) {
                if(data[column]) {
                  matchFound = (matchFound || data[column].toString().trim().toLowerCase().indexOf(filter.trim().toLowerCase()) !== -1)
                }
              }
            }
            return matchFound;
          }
        }
      

      每当您希望应用过滤器时,请将 dataSource 上的过滤器属性更新为要搜索的字符串值。

      applyFilter(searchValue: any) {
          this.dataSource.filter = this.filterText.trim().toLowerCase();
          }
      

      【讨论】:

        猜你喜欢
        • 2017-11-23
        • 2018-09-22
        • 2019-10-15
        • 1970-01-01
        • 2023-02-08
        • 1970-01-01
        • 2021-09-19
        • 2020-08-21
        相关资源
        最近更新 更多