项目要求angular表格宽度可拖拽拉伸宽度,项目使用的的为ant-desigin组件库。为了方便使用,将其封装为指令。指令的主代码如下 1、dynamicColumnWidth.directive.ts
/**
* table宽度的拉伸和记录上次拉伸宽度 并进行初始化赋值(表格中设置nzWidthConfig的话 此拖拽指令会不生效、)
* 使用方法:
* 1、单纯拖拽宽度,不需要下次默认显示上次的拖拽宽度
* th上 [appDynamicColumnWidth]
* 2、拖拽宽度后 默认显示上次拖拽的宽度
* 表头th和表格td 上 [appDynamicColumnWidth] [isSetDefaultWidth]="true"
*/
import {Directive, ElementRef, HostListener, Input, OnDestroy, OnInit, Renderer2} from '@angular/core';
@Directive({
selector: '[appDynamicColumnWidth]',
})
export class DynamicColumnWidthDirective implements OnInit, OnDestroy {
@Input('appDynamicColumnWidth') appDynamicColumnWidth;
// minWidth 最小宽度
@Input('minWidth') minWidth: number;
// 是否将宽度默认赋值
@Input('isSetDefaultWidth') isSetDefaultWidth: Boolean = false;
public originClientX = 0;
public originClientY = 0;
public elementWidth = 0;
public elementHeight = 0;
public isChanging: Boolean = false;
private thElement;
constructor(private el: ElementRef, private rd: Renderer2) {
}
ngOnInit() {
if (this.el.nativeElement.localName === 'th') {
this.setDragHandle(this.el.nativeElement);
}
this.setColumnWidth(this.el.nativeElement);
}
/**
* 设置宽度
* @param element
*/
setColumnWidth(element) {
if (this.isSetDefaultWidth) {
let columnWidthItems = localStorage.getItem('columnWidth');
if (columnWidthItems) columnWidthItems = JSON.parse(columnWidthItems);
const loactionHash = this.getLocationUrl();
const columnWidthItem = columnWidthItems[loactionHash];
if (columnWidthItem) element.style.width = columnWidthItem[element.cellIndex];
}
}
/**
* 将对应拖拽方向 插入可拖拽的dom节点
*/
setDragHandle(element) {
const handel = `<div class="dragTableHandel rightHandel" ></div>`;
this.setColumnWidth(element);
element.style.position = 'relative';
element.appendChild(this.createDocumentFragment(handel));
}
/***
* 根据字符串模板创建dom
* @param templateString
*/
createDocumentFragment(templateString) {
return document.createRange().createContextualFragment(templateString);
}
/**
* 元素拖拽节点的 鼠标mounseDown事件,记录初始值
* @param event
*/
@HostListener('document:mousedown', ['$event'])
onHandleMouseDown(event) {
if (event.target.className && event.target.className.indexOf('dragTableHandel') > -1) {
this.thElement = event.target.parentElement;
this.isChanging = true;
this.originClientX = event.clientX;
this.originClientY = event.clientY;
// 获取此时元素的宽高
this.elementWidth = this.thElement.offsetWidth;
this.elementHeight = this.thElement.offsetHeight;
}
}
@HostListener('document:mousemove', ['$event'])
onHandleMouseMove(event) {
if (this.isChanging) {
const clientX = event.clientX;
let width = this.elementWidth + (clientX - this.originClientX);
if (width < this.minWidth) width = this.minWidth;
const trElement = this.thElement.offsetParent.querySelector('tbody tr');
let tdElement;
// 获取要改变宽度的td
if (trElement) {
const tdElements = Array.from(trElement.querySelectorAll('td'));
tdElement = tdElements[this.thElement.cellIndex];
}
if (width) {
if (tdElement) tdElement.style.width = width + 'px';
this.thElement.style.width = width + 'px';
}
}
}
@HostListener('document:mouseup', ['$event'])
onHandleMouseUp() {
if (this.thElement && this.thElement.localName === 'th') {
this.isChanging = false;
const allPageColumn = localStorage.getItem('columnWidth');
const loactionHash = window.location.hash;
let allPageColumnItems = {};
if (allPageColumn) {
allPageColumnItems = JSON.parse(allPageColumn);
}
this.recordColumnWidth(allPageColumnItems);
}
}
/**
* 获取当前页面URL
*/
getLocationUrl() {
let loactionHash = window.location.hash;
// 获取当前页面记录的表格列表宽度
if (loactionHash) loactionHash = loactionHash.split('?')[0];
return loactionHash;
}
/**
* 记录列宽 保存到本地
* @param columnItems
* @param columnWidth
*/
recordColumnWidth(columnItems: Object = {}, columnWidth: Object = {}) {
const loactionHash = this.getLocationUrl();
let pageColumnWidth = columnItems[loactionHash];
if (!pageColumnWidth) pageColumnWidth = {};
const index = this.thElement.cellIndex;
pageColumnWidth[index] = this.thElement.style.width;
columnItems[loactionHash] = pageColumnWidth;
localStorage.setItem('columnWidth', JSON.stringify(columnItems));
}
ngOnDestroy(): void {
const dragHandleNodeList = document.querySelectorAll('.dragTableHandel');
for (let i = 0; i < dragHandleNodeList.length; i++) {
dragHandleNodeList[i].remove();
}
}
}
2、在对应使用指令的module中引入指令。
import {DynamicColumnWidthDirective} from '@shared/dynamicColumnWidth.directive';
@NgModule({
imports: [
],
declarations: [
// your components
DynamicColumnWidthDirective
],
exports: [
DynamicColumnWidthDirective
],
})
export class SharedModule {
}
3、在对应的功能页面使用(当前使用方式会默认保存上次拉伸的宽度,并且进行赋值)
<nz-table class="bline" [nzData]="cusList" [nzShowPagination]="false"
[nzTotal]="customRequest.total" [(nzLoading)]="customRequest.loading"
[nzScroll]="{ y:'600px'}"
>
<thead>
<tr class="spec-thead-tr">
<th nzShowCheckbox nzLeft="0px" [(nzChecked)]="allChecked"
[nzIndeterminate]="indeterminate" (nzCheckedChange)="tableCheckAll($event)">
</th>
<th nzWidth="100px">
编码
</th>
<th [appDynamicColumnWidth] [isSetDefaultWidth]="true">
<p>客户名称</p>
</th>
<th [appDynamicColumnWidth] [isSetDefaultWidth]="true" nzWidth="300">
国家地区
</th>
<th [appDynamicColumnWidth] [isSetDefaultWidth]="true" nzWidth="200">客户来源</th>
<th [appDynamicColumnWidth] [isSetDefaultWidth]="true" nzWidth="200">
<p>客户等级</p>
</th>
</tr>
</thead>
<tbody class="spe-tbody">
<tr *ngFor="let data of cusList" style="cursor: pointer">
<td></td>
<td></td>
<td [appDynamicColumnWidth] [isSetDefaultWidth]="true"></td>
<td [appDynamicColumnWidth] [isSetDefaultWidth]="true"></td>
<td [appDynamicColumnWidth] [isSetDefaultWidth]="true"></td>
<td [appDynamicColumnWidth] [isSetDefaultWidth]="true"></td>
</tr>
</tbody>
</nz-table>