p-table 过滤器 header 中的 primeng p-calendar,允许使用手动输入日期并清除它
primeng p-calendar in p-table filter header, allow use to enter date manually and clear it
我在 table 的 header 中使用 primeng 的 p-calendar 作为过滤器。我需要 select 一个日期,但也需要手动输入一个日期,因此必须使用 handleSelection 方法实现一个 injectable 服务。丑陋的问题是我目前必须 return 当前 selectedValue 并将其分配给前一个。
有没有办法将 previousStartDate(日期类型)作为参考传递,这样我就可以在 handleSelection 函数中更新它而不是 return是吗?
<p-calendar #startDate appendTo="body" dateFormat="dd M yy"
(onSelect)="previousStartDate = calendarService.handleSelection(dt, startDate, 'startDate', 'equals', previousStartDate)"
(onBlur)="previousStartDate = calendarService.handleSelection(dt, startDate, 'startDate', 'equals', previousStartDate)"
styleClass="sym-column-filter">
</p-calendar>
我的 handleSelection 函数如下所示
@Injectable({
providedIn: 'root'
})
export class CalendarService {
constructor(private dateService: DateService) {}
/*
To be used for the p-table filters where the filter is a p-calendar
This allows us to also enter the date manually in the text box
*/
handleSelection(dt: Table, calendar: Calendar, field: string, comparisonMethod: string, previousDate: Date | null): Date | null {
// only continue if the value has changed from the previous one
if (calendar.value === previousDate) {
return;
}
// If there is a date then filter by that
if (calendar.value) {
dt.filter(this.dateService.formatDate(calendar.value), field, comparisonMethod);
} else {
// Otherwise we may have removed some text so need to refresh the p-table
dt.filter('', field, comparisonMethod);
}
return calendar.value;
}
}
只是拍一张它的样子
我玩了更多,发现了另一种方法,实际上更简单。而不是使用 onSelect 和 onBlur 我发现你可以使用 ngModelChange 调用。
在 p-table header 中使用 p-calendar 似乎有一些限制,尤其是当您想在 select 中输入日期时(现有最常见的方法)。对我来说,我想输入文本,但也希望它在清除(无值)时发出过滤请求。这种方法就是这样做的,它会忽略无效日期,但会在它为空或具有有效日期时发出请求。
标记如下:
<p-calendar
#endDate
[(ngModel)]="endDateFilter"
(ngModelChange)="calendarService.calendarDateChanged($event, endDate, dt, 'endDate', 'equals')"
appendTo="body"
dateFormat="dd M yy"
placeholder="Select"
styleClass="sym-column-filter">
</p-calendar>
现在我的助手服务看起来像这样:
import { Injectable } from '@angular/core';
import { Calendar } from 'primeng/calendar';
import { Table } from 'primeng/table';
import { DateService } from './date.service';
/**
* The calendar helper service is a common injectable service that can handle entering a date in the p-calendar when the p-calendar
* is used as a filter header
*/
@Injectable({
providedIn: 'root'
})
export class CalendarService {
constructor(private dateService: DateService) {}
/*
To be used for the p-table filters where the filter is a p-calendar
This allows us to also enter the date manually in the text box
*/
calendarDateChanged(calendarDate: Date | null, calendar: Calendar, table: Table, field: string, comparisonMethod: string) {
// We do a setTimeout to give it one tick of time to make sure the selected date is populated
// If we don't do this then the date will be an empty string even though they may have selected a date
setTimeout(() => {
// Get the DOM input field to check the text, this is primarily to check of the value has been cleared
// so we need to reset the filter
const calendarInput = calendar?.el.nativeElement.querySelector('input');
if (calendarInput) {
const enteredValue = calendarInput.value;
// check it is a valid date or is empty for clearing the filter
if (calendarDate || enteredValue === '') {
table.filter(enteredValue === '' ? null : this.dateService.formatDate(calendar.value), field, comparisonMethod);
}
}
}, 1);
}
}
然后我可以通过将它作为服务注入来在我的组件中使用它,必须使其成为 public 以便标记调用它。
endDateFilter: Date | null;
constructor(
public calendarService: CalendarService
) { }
我在 table 的 header 中使用 primeng 的 p-calendar 作为过滤器。我需要 select 一个日期,但也需要手动输入一个日期,因此必须使用 handleSelection 方法实现一个 injectable 服务。丑陋的问题是我目前必须 return 当前 selectedValue 并将其分配给前一个。
有没有办法将 previousStartDate(日期类型)作为参考传递,这样我就可以在 handleSelection 函数中更新它而不是 return是吗?
<p-calendar #startDate appendTo="body" dateFormat="dd M yy"
(onSelect)="previousStartDate = calendarService.handleSelection(dt, startDate, 'startDate', 'equals', previousStartDate)"
(onBlur)="previousStartDate = calendarService.handleSelection(dt, startDate, 'startDate', 'equals', previousStartDate)"
styleClass="sym-column-filter">
</p-calendar>
我的 handleSelection 函数如下所示
@Injectable({
providedIn: 'root'
})
export class CalendarService {
constructor(private dateService: DateService) {}
/*
To be used for the p-table filters where the filter is a p-calendar
This allows us to also enter the date manually in the text box
*/
handleSelection(dt: Table, calendar: Calendar, field: string, comparisonMethod: string, previousDate: Date | null): Date | null {
// only continue if the value has changed from the previous one
if (calendar.value === previousDate) {
return;
}
// If there is a date then filter by that
if (calendar.value) {
dt.filter(this.dateService.formatDate(calendar.value), field, comparisonMethod);
} else {
// Otherwise we may have removed some text so need to refresh the p-table
dt.filter('', field, comparisonMethod);
}
return calendar.value;
}
}
只是拍一张它的样子
我玩了更多,发现了另一种方法,实际上更简单。而不是使用 onSelect 和 onBlur 我发现你可以使用 ngModelChange 调用。
在 p-table header 中使用 p-calendar 似乎有一些限制,尤其是当您想在 select 中输入日期时(现有最常见的方法)。对我来说,我想输入文本,但也希望它在清除(无值)时发出过滤请求。这种方法就是这样做的,它会忽略无效日期,但会在它为空或具有有效日期时发出请求。
标记如下:
<p-calendar
#endDate
[(ngModel)]="endDateFilter"
(ngModelChange)="calendarService.calendarDateChanged($event, endDate, dt, 'endDate', 'equals')"
appendTo="body"
dateFormat="dd M yy"
placeholder="Select"
styleClass="sym-column-filter">
</p-calendar>
现在我的助手服务看起来像这样:
import { Injectable } from '@angular/core';
import { Calendar } from 'primeng/calendar';
import { Table } from 'primeng/table';
import { DateService } from './date.service';
/**
* The calendar helper service is a common injectable service that can handle entering a date in the p-calendar when the p-calendar
* is used as a filter header
*/
@Injectable({
providedIn: 'root'
})
export class CalendarService {
constructor(private dateService: DateService) {}
/*
To be used for the p-table filters where the filter is a p-calendar
This allows us to also enter the date manually in the text box
*/
calendarDateChanged(calendarDate: Date | null, calendar: Calendar, table: Table, field: string, comparisonMethod: string) {
// We do a setTimeout to give it one tick of time to make sure the selected date is populated
// If we don't do this then the date will be an empty string even though they may have selected a date
setTimeout(() => {
// Get the DOM input field to check the text, this is primarily to check of the value has been cleared
// so we need to reset the filter
const calendarInput = calendar?.el.nativeElement.querySelector('input');
if (calendarInput) {
const enteredValue = calendarInput.value;
// check it is a valid date or is empty for clearing the filter
if (calendarDate || enteredValue === '') {
table.filter(enteredValue === '' ? null : this.dateService.formatDate(calendar.value), field, comparisonMethod);
}
}
}, 1);
}
}
然后我可以通过将它作为服务注入来在我的组件中使用它,必须使其成为 public 以便标记调用它。
endDateFilter: Date | null;
constructor(
public calendarService: CalendarService
) { }