【问题标题】:Angular Material data table column sort by date rangeAngular Material 数据表列按日期范围排序
【发布时间】:2019-08-26 06:38:21
【问题描述】:

如何根据日期范围对日期列进行排序?角材料数据表。我正在做一个项目,现在面临一个问题,即如何使用 filterPredicate 或 mat-table 中的任何其他选项根据日期范围 fromDate 和 toDate 对数据进行日期列排序。

日期列将显示在日期范围之间。请参考截图并查看stackblitz中的项目here

https://stackblitz.com/edit/angular-pkkvbd-cdtxwz-date-range-filter?embed=1&file=app/table-filtering-example.ts

如果我选择 2019 年 1 月 1 日2020 年 12 月 31 日,数据将显示所有日期之间的结果

【问题讨论】:

    标签: angular angular-material


    【解决方案1】:

    TL;DR:https://stackblitz.com/edit/angular-pkkvbd-cdtxwz-date-range-filter-jzlwxr?file=app/table-filtering-example.ts

    您不仅要对表格进行排序,还要过滤表格。 考虑到您使用的是角材料,这些是角材料中的分离问题。您必须首先提供过滤组件并使用该数据来实现 filterPredicate 函数手动,是的手动。

    过滤:

    export class TableFilteringExample {
      displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
      dataSource = new MatTableDataSource(ELEMENT_DATA);
    
      applyFilter(filterValue: string) {
        this.dataSource.filterPredicate = filterPeriod;
      }
    
      filterPeriod(data: T, filter: string) {
        return data.referenceDate > startDateFilter.value() && data.referenceDate < endDateFilter.value();
      }
    }
    
    

    排序功能也可用于您的 material.table 组件,但此组件为您提供开箱即用的功能。参考https://material.angular.io/components/table/overview#sorting 关于如何正确使用 MatSort 组件:

    <table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
    ...
    

    然后,在您的 .ts 组件中,您将 matSort 称为:

        @ViewChild(MatSort, {static: true}) sort: MatSort;
    

    如果您想完成故事和阅读小册子以了解如何根据您的案例调整材料组件,您需要完成几个步骤。我建议你从这里开始你的旅程https://material.angular.io/components/table/overview#sorting

    【讨论】:

    【解决方案2】:

    为了达到你预期的效果,你需要改变dataSource类型。您还需要一种方法来根据用户的日期范围选择重建您的项目数组。

    您的xxx.component.ts 应该如下所示。

    import { Component } from '@angular/core';
    import { MatTableDataSource } from '@angular/material';
    import { DatePipe } from '@angular/common';
    import {FormControl, FormGroup} from '@angular/forms';
    import * as moment from 'moment';
    
    export interface PeriodicElement {
      name: string;
      position: number;
      weight: number;
      DOB: Date;
      created: Date;
    }
    
    const ELEMENT_DATA: PeriodicElement[] = [
      { position: 1, name: 'Hydrogen', weight: 1.0079, DOB: new Date(2016, 11, 24), created: new Date(2015, 15, 24) },
      { position: 2, name: 'Helium', weight: 4.0026, DOB: new Date(2018, 18, 24), created: new Date(2018, 11, 24) },
      { position: 3, name: 'Lithium', weight: 6.941, DOB: new Date(1993, 6, 12), created: new Date(1999, 12, 15) },
      { position: 4, name: 'Beryllium', weight: 9.0122, DOB: new Date(2001, 7, 6), created: new Date(2011, 10, 6) },
      { position: 5, name: 'Boron', weight: 10.811, DOB: new Date(2020, 5, 9), created: new Date(2020, 5, 9) },
      { position: 6, name: 'Carbon', weight: 12.0107, DOB: new Date(2008, 7, 14), created: new Date(2008, 7, 14) },
      { position: 7, name: 'Nitrogen', weight: 14.0067, DOB: new Date(1998, 11, 18), created: new Date(1998, 11, 18) },
      { position: 8, name: 'Oxygen', weight: 15.9994, DOB: new Date(2002, 2, 24), created: new Date(2002, 2, 24) },
      { position: 9, name: 'Fluorine', weight: 18.9984, DOB: new Date(2006, 4, 29), created: new Date(2006, 4, 29) },
      { position: 10, name: 'Neon', weight: 20.1797, DOB: new Date(2040, 5, 30), created: new Date(2040, 5, 30) },
    ];
    
    /**
     * @title Table with filtering
     */
    @Component({
      selector: 'table-filtering-example',
      styleUrls: ['table-filtering-example.css'],
      templateUrl: 'table-filtering-example.html',
    })
    export class TableFilteringExample {
      displayedColumns: string[] = ['position', 'name', 'weight', 'DOB', 'founded'];
      dataSource = ELEMENT_DATA;
      pipe: DatePipe;
    
    filterForm = new FormGroup({
        fromDate: new FormControl(),
        toDate: new FormControl(),
    });
    
    get fromDate() { return this.filterForm.get('fromDate'); }
    get toDate() { return this.filterForm.get('toDate'); }
    
      constructor() {
      }
    
      getDateRange(value) {
        // getting date from calendar
        const fromDate = value.fromDate
        const toDate = value.toDate
        const tempData = <any>this.dataSource;
        let selectedItems: PeriodicElement[] = [];
        if(fromDate !== '' && toDate !== '') {
                  tempData.forEach((item, index) => {
                if (item.DOB >= fromDate && item.DOB <= toDate) {
                    selectedItems.push(item);
                }
            });
    
            this.dataSource = selectedItems;
        }
      }
    
    
      applyFilter(filterValue: string) {
        // this.dataSource.filter = filterValue.trim().toLowerCase();
      }
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用过滤功能。

      getDateRange(value) {
          this.dataSource.data = ELEMENT_DATA;
          const fromDate = value.fromDate
          const toDate = value.toDate
          this.dataSource.data = this.dataSource.data.filter(e=>e.DOB > fromDate && e.DOB < toDate ) ;
        }
      

      filter() 方法创建一个包含所有通过的元素的新数组 由提供的函数实现的测试。

      More information about filter function

      Stackblitz example based on your example.

      【讨论】:

      • 如何在“this.dataSource.filterPredicate”而不是“thisdataSource.data”中过滤日期范围。
      • 嗯,这有点复杂,因为您需要用自己的逻辑包装过滤器函数。你想让我补充一下我写这种逻辑的例子吗?
      • 在我的项目中,我使用了带有 filterPredicate 的多表单自定义过滤器,例如名称字段、状态、日期范围过滤器等,因此日期范围将与所有其他表单字段一起排序。
      【解决方案4】:

      如果您想为过滤和排序应用自定义行为,那么您可以应用如下内容:

      自定义过滤示例(在您的构造函数中):

      this.dataSourceUPs.filterPredicate = (data: UPs, filter: string) => {
        filter = filter.trim().toLowerCase();
        return this.contains(data.nombreUP, filter) || this.contains(data.ciudad, filter) || this.contains(Number(data.fechaInicio.split("T")[0].split("-")[2]), filter);
      }
      

      自定义排序示例:

      compare(a: number | string, b: number | string, isAsc: boolean) {
          return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
      }
      sortDataUPs(sort: Sort) {
          const data = this.dataSourceUPs.data.slice();
          if (!sort.active || sort.direction === '') {
            this.dataSourceUPs.data = data;
            return;
          }
      
          this.dataSourceUPs.data = data.sort((a, b) => {
            const isAsc = sort.direction === 'asc';
            switch (sort.active) {
              case 'periodo': return this.compare(a.periodo, b.periodo, isAsc);
              case 'nombreUP': return this.compare(a.nombreUP, b.nombreUP, isAsc);
              case 'ciudad': return this.compare(a.ciudad, b.ciudad, isAsc);
              case 'programa': return this.compare(a.nombreEdicion + '-' + a.nombrePrograma, b.nombreEdicion + '-' + b.nombrePrograma, isAsc);
              default: return 0;
            }
          });
        }
      

      大小写是您在 html ng-container 中放入 matColumnDef 的值,它们是您放入 displayColumns 数组的列名。 剩下要做的就是将绑定应用到您的表,如下所示:

      <table mat-table [dataSource]="dataSourceUPs" class="mat-elevation-z8" style="width: 100%;" matSort (matSortChange)="sortDataUPs($event)">
      

      您可以注意到案例“programa”是自定义的。 您很可能需要做出正确的导入语句,例如针对排序类型。

      【讨论】:

        猜你喜欢
        • 2017-06-03
        • 2012-09-17
        • 1970-01-01
        • 1970-01-01
        • 2015-08-02
        • 2014-11-06
        • 2017-11-15
        • 1970-01-01
        • 2019-01-02
        相关资源
        最近更新 更多