1)需求:
AngularJS6,项目的一个页面需要展示n*n的可扩展的数据矩阵,并且拥有权限的用户可以对矩阵数据进行修改。
2)思路:
PrimeNG,使用p-table、p-dropdown,利用ngFor来动态生成。
html:
<p-table [columns]="options" [value]="dataprovider">
<ng-template pTemplate="header">
<tr>
<th rowspan="2">{{headerText1}}</th>
<th [attr.colspan]="optionHeads.length">{{headerText2}}</th>
</tr>
<tr>
<th *ngFor="let col of optionHeads">{{col}}</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-rowIndex="rowIndex">
<tr >
<td>{{rowData.headText}}</td>
<td *ngFor=let item of rowData.list">
<p-dropdown [ngModel]="item" [options]="options"
(onChange)="onChange($event)"></p-dropdown>
</td>
</tr>
</ng-template>
</p-table>
3) 遇到的问题:
- 在生成的table中,点击p-dropdown控件,不出下拉菜单。
- ngModel不能双向绑定,编辑数据后无法保存。
4) 解决方法:
<p-table [columns]="options" [value]="dataProvider">
<ng-template pTemplate="header">
<tr>
<th rowspan="2">{{headerText1}}</th>
<th [attr.colspan]="optionHeads.length">{{headerText2}}</th>
</tr>
<tr>
<th *ngFor="let col of optionHeads">{{col}}</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-rowIndex="rowIndex">
<tr [pSelectableRow]="rowData" [pSelectableRowIndex]="rowIndex">
<td>{{rowData.headerText}}</td>
<td *ngFor="let item of dataProvider[rowIndex].list; index as colIndex">
<p-dropdown [options]="options" [(ngModel)]="matrix[rowIndex][colIndex]"
(onChange)="onChange($event)" appendTo="body"></p-dropdown>
</td>
</tr>
</ng-template>
</p-table>
5) 总结
- appendTo="body"可以解决点击不弹菜单的问题。
- 在使用[(ngModel)]="matrix[rowIndex][colIndex]"生成数据矩阵时,绑定dataProvider会出现一个莫名其妙的错误:前段控件显示的数据与内存数据不符合的bug。单独写一个cloneMatrix函数,克隆一个新的列表matrix解决这个问题。
- 管理员权限控制通过disabled实现,这里没有写出。