功能目标:
点击表格中一行,可向上、向下调整顺序。如下图,点【向下】按钮后第一行、第二行交换顺序。
组件:LayersWindow
利用primeng的table实现表格功能,html如下
<p-dialog header="layers" [(visible)]="display">
<p-table #table [columns]="cols" [value]="layers" selectionMode="single" [(selection)]="selectedLayer" [style]="{'width':'25em','height':'15em','table-layout':'auto!important'}" dataKey="name" editMode="row" [scrollable]="true">
<ng-template pTemplate="body" let-layer let-columns="columns">
<tr [pSelectableRow]="layer">
<td [style]="{'width':'3em'}">
<a [ngClass]="layer.locked?'pi pi-lock':'pi pi-lock-open'" (click)="layer.locked=!layer.locked"></a>
</td>
<td [style]="{'width':'3em'}">
<a [ngClass]="layer.visable?'fa fa-eye':'fa fa-eye-slash'" (click)="layer.visable=!layer.visable"></a>
</td>
<td (dblclick)="beforerename(layer)">{{layer.name}}</td>
</tr>
</ng-template>
</p-table>
<p-footer>
<button type="button" pButton icon="pi pi-caret-down" [disabled]="!selectedLayer||atTop(selectedLayer)" (click)="toBack(selectedLayer)" title="toBack"></button>
<button type="button" pButton icon="pi pi-caret-up" [disabled]="!selectedLayer||atBottom(selectedLayer)" (click)="toFront(selectedLayer)" title="toFront"></button>
</div>
</p-footer>
</p-dialog>
对应的ts代码中,关键有3点:
- 在页面初始化完成 ngAfterViewInit(table子组件可访问)后,设定sortField、sortOrder = -1(降序),并调用sortSingle()初始化排序;
- 【向上】/【向下】按钮的disabled属性绑定atTop/atBottom方法;
- 【向上】/向下】按钮点击时与上一行/下一行调换zIndex。
import { Component, Input, ViewChild, AfterViewInit } from '@angular/core';
import { Table } from 'primeng/table/table';
@Component({
selector: 'app-layers-window',
templateUrl: './layers.component.html',
styleUrls: ['./layers.component.css']
})
export class LayersWindow implements AfterViewInit {
@ViewChild('table', { static: false }) dt: Table;
@Input() display: boolean;
cols: any[];
layers: Layer[];
selectedLayer: Layer;
constructor() {
this.display = false;
this.cols = [
{ field: 'locked', header: 'locked' },
{ field: 'visible', header: 'visible' },
{ field: 'name', header: 'name' }
];
this.layers = [
{ locked: false, visible: true, name: "background", zIndex: 0 },
{ locked: true, visible: false, name: "untitledLayer", zIndex: 1 }
];
}
ngAfterViewInit() {
this.dt.sortField = "zIndex";
this.dt.sortOrder = -1;
this.dt.sortSingle();
}
toFront(layer: Layer) {
if(layer){
let i = layer.zIndex+1;
let b = this.getByZIndex(i);
if(b){b.zIndex = layer.zIndex;}
layer.zIndex=i;
this.dt.sortSingle();
}
}
toBack(layer: Layer) {
if(layer){
let i = layer.zIndex-1;
let b = this.getByZIndex(i);
if(b){b.zIndex = layer.zIndex;}
layer.zIndex=i;
this.dt.sortSingle();
}
}
atTop(layer: Layer):boolean{
if(layer){
return layer.zIndex==this.getMinZIndex();
}
return false;
}
private getMaxZIndex():number{
let maxzIndex=-1;
this.layers.forEach(each => {
if(each.zIndex>maxzIndex){
maxzIndex=each.zIndex;
}
});
return maxzIndex;
}
atBottom(layer: Layer):boolean{
if(layer){
return layer.zIndex==this.getMaxZIndex();
}
return false;
}
private getMinZIndex():number{
let minzIndex=Number.MAX_VALUE;
this.layers.forEach(each => {
if(each.zIndex<minzIndex){
minzIndex=each.zIndex;
}
});
return minzIndex;
}
private getByZIndex(zIndex:number):Layer{
let result = null;
this.layers.forEach(each => {
if(each.zIndex==zIndex){
result = each;
}
});
return result;
}
}
interface Layer {
locked: boolean;
visible: boolean;
name: string;
zIndex: number;
}
PRIMENG组件:
import { ButtonModule } from 'primeng/button';
import { TableModule } from 'primeng/table';
BYW:
图标中使用了primeng和fontawesome的图标,需要安装相应的包,并在angular.json中加入相应的css。
"styles": [
"node_modules/primeicons/primeicons.css",
"node_modules/font-awesome/css/font-awesome.min.css",
],