【问题标题】:Kendo ui Angular 2 date filter between 2 specific datesKendo ui Angular 2日期过滤器在2个特定日期之间
【发布时间】:2026-01-30 13:00:01
【问题描述】:

我在 kendo Ui grid angular 2 集成组件上创建日期过滤器时遇到问题。问题是我想过滤两个特定日期之间的日期列,我的意思是日期范围。我搜索了 Kendo 和 * 的论坛,但我没有找到任何东西。是否有人在 Kendo ui grid angular 2 组件中的两个日期之间过滤日期列有相同的经验。如果您能就这个问题举个例子,我将不胜感激。谢谢大家。

【问题讨论】:

    标签: angular kendo-ui kendo-grid datefilter


    【解决方案1】:

    很高兴看到您的代码能够准确确定您的具体案例的答案。

    无论如何,我为我的雇主创建了一个网格,其中包含您想要的功能,并且开箱即用的剑道组件。我的项目使用 angular 4、typescript 2.9 和带有 OData v4 的 WEB API。

    在我的具体情况下,唯一的解决方法是处理时间戳。在给出这个答案时,剑道网格在午夜以外的时间戳上表现不佳。

    这是component.html: **请注意,在kendo-grid 标签上设置filterable="menu" 并在日期列中设置filter="date" 是按照kendo's docs 设置日期过滤的一种官方方式。然后您可以使用format="" 设置您想要的日期格式

    <kendo-grid [filter]="GridState.filter" filterable="menu" (filterChange)="filterChange($event)" [data]="gridData(list)" [pageSize]="GridState.take"
            (dataStateChange)="onStateChange($event)" [skip]="GridState.skip" [sort]="GridState.sort" [sortable]="true" [pageable]="true"
            (sortChange)="sortChange($event)" [scrollable]="'none'">
        <kendo-grid-column field="ReturnStatusDisplay" title="Status" width="columnWidth">
        </kendo-grid-column>
        <kendo-grid-column field="Preparer.Id" title="Preparer Id" width="columnWidth" filter="numeric" format="{0:d}">
        </kendo-grid-column>
        <kendo-grid-column field="ReceivedDate" title="Received Date" width="columnWidth" filter="date" format="{0:MM/dd/yyyy}">
        </kendo-grid-column>
        <kendo-grid-column field="AdmCreatedDate" title="Processed Date" width="columnWidth" filter="date" format="{0:MM/dd/yyyy}">
        </kendo-grid-column>
      </kendo-grid>
    

    为了正确处理时间戳,我在打字稿上创建了一个方法来将所有时间戳设置为最近的午夜

    public setTimestampToNearestMidnight(entitySet: any[], dateProperty): any[] {
        entitySet.forEach(e => {
          let dateWithNearestMidnight = new Date(e[dateProperty]).setHours(0,0,0,0);
    
          e[dateProperty] = new Date(dateWithNearestMidnight);
        })
    
        return entitySet;
      }
    

    然后将它应用到我需要显示的对象列表中

    public get ReturnsList$(): Observable<Return[]> {
        let processedReturnsList: Return[] = this._accountManagementService._companyFolio.Returns;
        processedReturnsList = this._commonService.setTimestampToNearestMidnight(processedReturnsList, ReturnDateProperties.ADM_CREATED_DATE);
        processedReturnsList = this._commonService.setTimestampToNearestMidnight(processedReturnsList, ReturnDateProperties.RECEIVED_DATE);
        processedReturnsList = this.concatenateReturnTypeAndDescription(processedReturnsList);
    
        return Observable.of(processedReturnsList);
      }
    

    请注意我使用 observables 作为网格数据,然后使用异步管道订阅 HTML。 如果时间戳和 observables 不适用于您,您可以忽略 setTimestampToNearestMidnight()ReturnsList$() 部分。

    正如您在下面的屏幕截图中看到的,您可以使用菜单上的 AND 运算符来选择日期范围;在这种情况下,2018 年 7 月 31 日至 2018 年 8 月 29 日之间是所选范围。

    我希望这会有所帮助!

    【讨论】:

      【解决方案2】:

      我正在为 Angular 使用 Kendo UI Grid。 Angular 版本为 5,使用 TypeScript。

      主要问题是网格将日期呈现为字符串,当应用日期过滤器时,它会尝试将字符串类型与本质上不兼容的日期类型进行比较。

      为了规避这个问题,我使用了moment.js 库,它可以将字符串转换为日期格式,或者将日期转换为字符串格式,以便在两者之间进行比较。

      确保您在项目中正确引用了 momentjs。将此添加到您的 component.ts(在类导出之外,因为以下是纯 javascript 代码)。

      class Range {
        from: Date;
        to: Date;
      }
      
      // Custom Filter Operator: isWithin
      
      function isWithin(columnValue: Date, range: Range): boolean {
        if (columnValue) {
          return moment(columnValue).isBetween(moment(range.from), moment(range.to), 'minute', '[]');
        } else {
          return false;
        }
      }
      

      以下是 component.ts 中的打字稿代码,它基本上将自定义过滤器添加到 Kendo Grid 的过滤器中。每当更新日期选择器中的值时都会调用 onMinDateChange 和 onMaxDateChange 函数(请参阅 component.html 的代码),并且过滤器会自动更新。

        public onMinDateChange(value: Date): void {
          this.filterDateRange(value, this.filterValueDateMax);
        }
      
        public onMaxDateChange(value: Date): void {
          this.filterDateRange(this.filterValueDateMin, value);
        }
      
        public filterDateRange(min, max): void {
          this.filter.filters = [];
      
          if (min && max) {
            this.filter.filters.push({
              field: this.field,
              operator: isWithin,
              value: { from: min, to: max }
            });
          }
        }
      

      通过在component.ts中添加这一行来输入过滤器:

        @Input() public filter: CompositeFilterDescriptor;
      

      日期时间选择器(如果需要,可以只使用日期选择器)在 component.html 中定义如下:

        <div class="row">
          <kendo-datepicker [(value)]="filterValueDateMin" [format]="'MM/dd/yyyy HH:mm:ss'" (valueChange)="onMinDateChange($event)"> </kendo-datepicker>
          <kendo-timepicker [(value)]="filterValueDateMin" (valueChange)="onMinDateChange($event)"> </kendo-timepicker>
          </div>
        <div class="row">
          <kendo-datepicker [(value)]="filterValueDateMax" [format]="'MM/dd/yyyy HH:mm:ss'" (valueChange)="onMaxDateChange($event)"> </kendo-datepicker>
          <kendo-timepicker [(value)]="filterValueDateMax" (valueChange)="onMaxDateChange($event)"> </kendo-timepicker>
        </div>
      

      最后,这就是我在主网格的 html 中使用过滤器的方式:

       <ng-template kendoGridFilterMenuTemplate *ngIf="col.fieldName === 'insertFieldNameHere'"
                         let-filter="filter"
                         let-column="column"
                         let-filterService="filterService">
              <app-date-time-range-filter [headerTitle]="col.displayName"
                                          [filter]="filter"
                                          [field]="column.field">
              </app-date-time-range-filter>
            </ng-template>
      

      希望这会有所帮助。

      【讨论】: