PrimeNG DataTable 自定义排序或过滤 (Angular 2)
PrimeNG DataTable Custom Sorting or filtering (Angular 2)
我在 PrimeNg 的 sorting/Filtering 日期列中遇到问题 Datatable.As 我正在显示日期 "dd/mm/yyyy" 字符串。
- 如果使用模板显示 "dd/mm/yyyy" 则过滤器无法作为过滤器处理日期 ISO 格式的实际数据绑定。
- 如果从后端将数据转换为字符串格式,则排序不正确,因为它按字符串而不是日期排序。
我使用 moment.js 解决了这个问题,因为它更容易和更快,但是如果你想在没有任何框架的情况下做它,代码总是可以定制一点(我希望更多的 if 条件和字符串转换)
所以您必须将 moment.js 添加到您的项目中:
a) 通过将 src link 添加到您的主 html 索引文件(主 angular 选择器、polyfills 等)从这个站点 https://cdnjs.com/libraries/moment.js/
b) 但如果是生产环境,我建议通过 npm 添加它。 http://momentjs.com/docs/ 这里还有其他可能性。
那你必须在import语句下和@Component注解上面声明moment变量
declare var moment;
然后,如果您已经将 primeng 模块添加到您的项目中,在 primeng 的 p-dataTable 标签内的 html 文件中有 p-column 标签,在此标签中我们需要添加 sortable="custom" 和 (sortFunction)="mysort($event)" 像这样:
<p-column field="date" header="Data" sortable="custom" (sortFunction)="mysort($event)"></p-column>
使用 p 列标签显示的日期采用 DD.MM.YYYY 字符串格式,例如:03.01.2017
之后,在我们获取数据并将数据推送到数组的组件中,数组用于在 table 中显示数据,在我名为约会的示例中,我们需要添加名为 mysort 的函数(因为我们正在调用此函数在 html p 列标记中)
mysort(event) {
let comparer = function (a, b): number {
let formatedA = moment(a.date, "DD.MM.YYYY").format('YYYY-MM-DD');
let formatedB = moment(b.date, "DD.MM.YYYY").format('YYYY-MM-DD');
let result: number = -1;
if (moment(formatedB).isBefore(formatedA, 'day')) result = 1;
return result * event.order;
};
this.appointments.sort(comparer);
}
在我的示例中,a.date 和 b.date 是类似于“21.12.2016”的字符串,我们需要将其格式化为 YYYY-MM-DD。然后我们只是比较日期。
仅此而已,我检查了这段代码并且它有效。
我希望它能帮助别人,如果解释是用教程风格写的,请原谅,但这是我的第一个答案,我想以正确的方式来做:)
我和Relis一样解决了。但是,直到我重新分配 "this.appointments" 变量后它才起作用。
mysort(event) {
this.appointments.sort((appointmentA, appointmentB) => {
// Here the property date is a date string with the format 'dd/mm/yyyy'.
// In the constructor of moment(), the second paramater is
// the format of the string you're passing in.
const momentA = moment(appointmentA.date, 'dd/mm/yyyy');
const momentB = moment(appointmentB.date, 'dd/mm/yyyy');
if(momentB.isBefore(momentA)){
result = 1;
}
return result * event.order;
});
// This is the key here.
this.appointments = [...this.appointments];
}
首先感谢@Relis 提供了一个有用的答案,尽管我已经用它来解决了一些不同的问题。
关于这个问题,我相信这可以在没有任何额外的功能和回调的情况下解决,这些功能和回调会强制您在每次单击 header 时转换日期。
您只需要将模型和表示分开(用于排序和表示的模型以在数据中显示数据 table)
想象一下,我们有一个 object 的数组,具有日期属性:
let dataArray = [{date:'01/02/2016'},{date:'01/02/2017'}]
然后你可以用额外的 属性 sortableDate
:
扩展这个数组中的每个 object
let dataArray = [{date:'01.02.2016', sortableDate:'2016-02-01'},{date:'01.02.2017', sortableDate:'2017-02-01'}]
转换我也建议使用moment.js。现在您可以使用其中一个属性显示值,另一个属性进行排序:
<p-column [field]="'mySortableDate'" [header]="'Header name' [sortable]="true">
<ng-template let-col let-data="rowData" pTemplate="body">
<span>{{data.date}}</span>
</ng-template>
</p-column>
简单的把戏
<p-column field="StartDate" [editable]="true" header="Start Date">
<ng-template let-col let-car="rowData" pTemplate="body">
<span>{{car[col.field] | date: ' d,MMM,yyyy'}}</span>
</ng-template>
</p-column>
我在 PrimeNg 的 sorting/Filtering 日期列中遇到问题 Datatable.As 我正在显示日期 "dd/mm/yyyy" 字符串。
- 如果使用模板显示 "dd/mm/yyyy" 则过滤器无法作为过滤器处理日期 ISO 格式的实际数据绑定。
- 如果从后端将数据转换为字符串格式,则排序不正确,因为它按字符串而不是日期排序。
我使用 moment.js 解决了这个问题,因为它更容易和更快,但是如果你想在没有任何框架的情况下做它,代码总是可以定制一点(我希望更多的 if 条件和字符串转换)
所以您必须将 moment.js 添加到您的项目中: a) 通过将 src link 添加到您的主 html 索引文件(主 angular 选择器、polyfills 等)从这个站点 https://cdnjs.com/libraries/moment.js/ b) 但如果是生产环境,我建议通过 npm 添加它。 http://momentjs.com/docs/ 这里还有其他可能性。
那你必须在import语句下和@Component注解上面声明moment变量
declare var moment;
然后,如果您已经将 primeng 模块添加到您的项目中,在 primeng 的 p-dataTable 标签内的 html 文件中有 p-column 标签,在此标签中我们需要添加 sortable="custom" 和 (sortFunction)="mysort($event)" 像这样:
<p-column field="date" header="Data" sortable="custom" (sortFunction)="mysort($event)"></p-column>
使用 p 列标签显示的日期采用 DD.MM.YYYY 字符串格式,例如:03.01.2017
之后,在我们获取数据并将数据推送到数组的组件中,数组用于在 table 中显示数据,在我名为约会的示例中,我们需要添加名为 mysort 的函数(因为我们正在调用此函数在 html p 列标记中)
mysort(event) {
let comparer = function (a, b): number {
let formatedA = moment(a.date, "DD.MM.YYYY").format('YYYY-MM-DD');
let formatedB = moment(b.date, "DD.MM.YYYY").format('YYYY-MM-DD');
let result: number = -1;
if (moment(formatedB).isBefore(formatedA, 'day')) result = 1;
return result * event.order;
};
this.appointments.sort(comparer);
}
在我的示例中,a.date 和 b.date 是类似于“21.12.2016”的字符串,我们需要将其格式化为 YYYY-MM-DD。然后我们只是比较日期。
仅此而已,我检查了这段代码并且它有效。 我希望它能帮助别人,如果解释是用教程风格写的,请原谅,但这是我的第一个答案,我想以正确的方式来做:)
我和Relis一样解决了。但是,直到我重新分配 "this.appointments" 变量后它才起作用。
mysort(event) {
this.appointments.sort((appointmentA, appointmentB) => {
// Here the property date is a date string with the format 'dd/mm/yyyy'.
// In the constructor of moment(), the second paramater is
// the format of the string you're passing in.
const momentA = moment(appointmentA.date, 'dd/mm/yyyy');
const momentB = moment(appointmentB.date, 'dd/mm/yyyy');
if(momentB.isBefore(momentA)){
result = 1;
}
return result * event.order;
});
// This is the key here.
this.appointments = [...this.appointments];
}
首先感谢@Relis 提供了一个有用的答案,尽管我已经用它来解决了一些不同的问题。 关于这个问题,我相信这可以在没有任何额外的功能和回调的情况下解决,这些功能和回调会强制您在每次单击 header 时转换日期。 您只需要将模型和表示分开(用于排序和表示的模型以在数据中显示数据 table) 想象一下,我们有一个 object 的数组,具有日期属性:
let dataArray = [{date:'01/02/2016'},{date:'01/02/2017'}]
然后你可以用额外的 属性 sortableDate
:
let dataArray = [{date:'01.02.2016', sortableDate:'2016-02-01'},{date:'01.02.2017', sortableDate:'2017-02-01'}]
转换我也建议使用moment.js。现在您可以使用其中一个属性显示值,另一个属性进行排序:
<p-column [field]="'mySortableDate'" [header]="'Header name' [sortable]="true">
<ng-template let-col let-data="rowData" pTemplate="body">
<span>{{data.date}}</span>
</ng-template>
</p-column>
简单的把戏
<p-column field="StartDate" [editable]="true" header="Start Date">
<ng-template let-col let-car="rowData" pTemplate="body">
<span>{{car[col.field] | date: ' d,MMM,yyyy'}}</span>
</ng-template>
</p-column>