PrimeNG表可以按列排序。 https://www.primefaces.org/primeng/#/table/sort
它们也可以具有列组。 https://www.primefaces.org/primeng/#/table/colgroup
不幸的是,我很难让这两个功能一起工作。前者的示例代码简化了动态列生成的创建过程,但后者的示例代码要求手动对每个列进行编码。
我有一种编写代码的方式,在我看来它应该可以工作,并且可以正确构建和显示代码;但是单击排序图标时,它不会对数据进行排序。
这是我的代码(用于标识变量名):
<div *ngIf="(sourceObservableReturningAnArray$ | async) as arrayOfDataNeeded">
<p-table
[value]="arrayOfDataNeeded"
autoLayout="true"
sortField="firstSortedProperty"
[rows]="25">
<ng-template pTemplate="header" let-columns>
<tr>
<th rowspan="2" [pSortableColumn]="arrayOfDataNeeded.firstSortedProperty">
Header for First Property
<p-sortIcon [field]="arrayOfDataNeeded.firstSortedProperty"></p-sortIcon>
</th>
<th rowspan="2" [pSortableColumn]="arrayOfDataNeeded.secondSortedProperty">
Header for Second Property
<p-sortIcon [field]="arrayOfDataNeeded.secondSortedProperty"></p-sortIcon>
</th>
<th rowspan="2" [pSortableColumn]="arrayOfDataNeeded.thirdSortedProperty">
Header for Third Property
<p-sortIcon [field]="arrayOfDataNeeded.thirdSortedProperty"></p-sortIcon>
</th>
<th rowspan="2" [pSortableColumn]="arrayOfDataNeeded.fourthSortedProperty">
Header for Fourth Property
<p-sortIcon [field]="arrayOfDataNeeded.fourthSortedProperty"></p-sortIcon>
</th>
<th rowspan="2" [pSortableColumn]="arrayOfDataNeeded.fifthSortedProperty">
Header for Fifth Property
<p-sortIcon [field]="arrayOfDataNeeded.fifthSortedProperty"></p-sortIcon>
</th>
<th [pSortableColumn]="arrayOfDataNeeded.sixthSortedProperty" colspan="2">
Header with Subheadings
<p-sortIcon [field]="arrayOfDataNeeded.sixthSortedProperty"></p-sortIcon>
</th>
<th rowspan="2" [pSortableColumn]="arrayOfDataNeeded.seventhSortedProperty">
Header for Seventh Property
<p-sortIcon [field]="arrayOfDataNeeded.seventhSortedProperty"></p-sortIcon>
</th>
</tr>
<tr>
<th>Subheading 1</th>
<th>Subheading 2</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-data>
<tr>
<td>{{data.firstSortedProperty | currency}}</td>
<td>{{data.secondSortedProperty}}</td>
<td>{{data.thirdSortedProperty | date : 'shortTime'}}<br>{{data.thirdProperty | date : 'MM/dd/yyyy'}}</td>
<td>{{data.fourthSortedProperty}}%</td>
<td>{{data.fifthSortedProperty}}%</td>
<td>{{data.sixthSortedProperty}}%</td>
<td>{{data.additionalUnsortedProperty | currency}}</td>
<td>{{data.seventhSortedProperty}}</td>
</tr>
</ng-template>
</p-table>
</div>
我猜测问题出在排序字段的规范中:由于arrayOfDataNeeded是对象数组,但是具有要对其进行排序的属性的对象,也许我没有识别出对象的正确地使用相关财产。我对PrimeNG不够熟悉,不知道该怎么做。我可能可以通过对隐式上下文执行某些操作来修复它,但是我不确定该怎么做。
开始标记中的sortField =“ firstSortedProperty”可以完全按预期工作,因此数据源似乎没有问题。
如果看到我的错误,请指出!我很高兴回答澄清的问题,如果我对问题的描述不满意。我也乐于接受有关实现所需功能的替代方法的建议。
答案 0 :(得分:0)
因此,对于我的原始问题,至少有两个解决方案。第一个很快速,但是有代码味。第二个问题涉及更多,但也可能是解决我提出的问题的正确方法。
第一解决方案
1)首先,将以下内容添加到component.ts文件中:
cols: any[];
和
this.cols = [
{ field: 'firstSortedProperty', header: 'Header for First Property'},
{ field: 'secondSortedProperty', header: 'Header for Second Property'},
{ field: 'thirdSortedProperty', header: 'Header for Third Property'},
{ field: 'fourthSortedProperty', header: 'Header for Fourth Property'},
{ field: 'fifthSortedProperty', header: 'Header for Fifth Property'},
{ field: 'sixthSortedProperty', header: 'Header for Sixth Property'},
{ field: 'additionalUnsortedProperty', header: '[It Doesn't Show, So Whatever]'},
{ field: 'seventhSortedProperty', header: 'Header for Seventh Property'},
];
2)然后,在component.html文件中,将[columns] =“ cols”添加到p表属性中。
<p-table
[value]="arrayOfDataNeeded"
[columns]="cols"
autoLayout="true"
sortField="firstSortedProperty"
[rows]="25">
说明:通过为p表提供column属性的值,可以访问在每一列中找到的字段名称。 假定的columns属性包含一个将从中动态生成列的数组,但是您没有这样做。 (Tricksy!)目前,它可以正常工作,尽管目前尚无法确定将来对PrimeNG的更改是否会破坏该解决方法。
第二个解决方案
实际上可以动态生成列,同时使用标题和子标题。
1)为了实现这一点,我们必须向cols数组中的对象添加更多属性。
this.cols = [
{ field: 'firstSortedProperty', header: 'Header for First Property', hasSubs: false, isSub: false},
{ field: 'secondSortedProperty', header: 'Header for Second Property', hasSubs: false, isSub: false},
{ field: 'thirdSortedProperty', header: 'Header for Third Property', hasSubs: false, isSub: false},
{ field: 'fourthSortedProperty', header: 'Header for Fourth Property', hasSubs: false, isSub: false},
{ field: 'fifthSortedProperty', header: 'Header for Fifth Property', hasSubs: false, isSub: false},
{ field: 'sixthSortedProperty', header: 'Header for Sixth Property', hasSubs: true, isSub: false},
{ field: 'additionalUnsortedProperty', header: '[It Doesn't Show, So Whatever]', hasSubs: false, isSub: true},
{ field: 'seventhSortedProperty', header: 'Header for Seventh Property', hasSubs: false, isSub: false},
];
请注意,has第六的hasSubs属性为true。此属性指示标题具有子标题,并将在html文件中用于更改。
的创建。可以从数组中省略extraUnsortedProperty对象,但我在此处包括该对象,以指示您如何动态生成子标题。我正在提供的解决方案仍然静态地指定了子标题,因为我试图着重于解决方案的基本要素。剩下的一点留给读者练习。 (我很懒?)
2)接下来,我们需要更改component.html文件中生成列的方式。我们将使用* ngIf为没有副标题的列提供一种格式设置,为有副标题的列提供另一种格式设置。
<ng-template pTemplate="header" let-columns>
<tr [hidden]="loadOffersTable.isEmpty()">
<th></th>
<ng-container *ngFor="let col of columns">
<ng-container *ngIf="col.hasSubs; else noSubs">
<th colspan="2" [pSortableColumn]="col.field">
{{col.header}}
<p-sortIcon [field]="col.field" ariaLabel="Activate to sort" ariaLabelDesc="Activate to sort in descending order" ariaLabelAsc="Activate to sort in ascending order"></p-sortIcon>
</th>
</ng-container>
<ng-template #noSubs>
<th *ngIf="!col.isSub" rowspan="2" [pSortableColumn]="col.field">
{{col.header}}
<p-sortIcon [field]="col.field"></p-sortIcon>
</th>
</ng-template>
</ng-container>
</tr>
<tr>
<th></th>
<th>Subheading 1</th>
<th>Subheading 2</th>
</tr>
</ng-template>
两列之间的格式差异主要取决于我们在其中任一列上设置的colspan和rowspan属性。如果它具有子标题,则设置colspan =“ 2”,以便该标题跨越两个子列。如果没有子标题,则设置rowspan =“ 2”,以便该标题也填充子标题行(对于该列)。 (不幸的是,您不能通过同时使用rowpan和colspan来尝试任何超豪华的东西。它必须是一个或另一个。)
还请注意使用逻辑容器以便在条件设置之外处理* ngFor。您需要* ngFor才能遍历各列,但是如果* ngFor位于标记内(如在通常为动态列生成而给出的示例中),则不能有条件地设置表头。 / p>
3)子标题代码实际上将保持不变。如果您要整理代码以使子标题也可以动态生成,则可以进行必要的更改。
现在,所有内容都是动态生成的,它为诸如此类的内容打开了选项:
奖励!
您可能仍然认为您需要静态列,因为表设计需要对不同列中的数据进行不同格式或管道传输。 (如果您这么认为的话,您很可能只是个新手,但是我们都是以这种方式开始的。)幸运的是,您已经设置了一些问题,可以使用cols数组解决该问题。将[ngSwitch]与field属性一起使用,以标识单元格中正在显示哪个列的数据,并相应地设置单元格的格式。您仍然需要遍历各列,但是* ngFor可以出现在标记中了。现在,逻辑容器将出现在单元格内部中,并确定如何显示单元格的内容。这是您要做的事情的开始:
<ng-template pTemplate="body" let-nameForDataObject let-columns="columns">
<tr>
<td *ngFor="let col of columns">
<ng-container [ngSwitch]="col.field">
<ng-container *ngSwitchCase="'firstSortedProperty'">{{nameForDataObject.firstSortedProperty}}</ng-container>
<ng-container *ngSwitchCase="'secondSortedProperty'">{{nameForDataObject.secondSortedProperty}}</ng-container>
...等等。 (使用switch语句格式化表数据不是一个聪明的技巧,也不是一个新的技巧,但是对于PrimeNG的新手来说,如何使其工作可能并不明显。)
我希望这些解决方案可以帮助您快速正确地设置PrimeNG表。祝好运!