一、技术框架及版本

JS框架 Angular,版本:6.0.0
UI框架 ng-zorro,版本:1.8.1

二、前提

搭建Angular环境
在Angular项目中引入ng-zorro
创建一个自定义指令,用于监听鼠标事件
在要监听的table 单元格元素标签上使用自定义指令

  下面用一个demo示例来说明:

三、代码

在组件模板上使用ng-zorro table ,components.component.html

 1 <div nz-row nzGutter="0">
 2   <div nz-col nzSpan="20" nzOffset="2">
 3       <nz-table   nzBordered #ajaxTable nzShowSizeChanger [nzFrontPagination]="false" [nzData]="tableDatas" [nzLoading]="loading"
 4       [nzTotal]="totalItems" [(nzPageIndex)]="currentPage" [(nzPageSize)]="itemsPerpage" (nzPageIndexChange)="getData()" (nzPageSizeChange)="getData()">
 5       <thead >
 6         <tr>
 7           <th appDynamicColumnWidth>ID</th>
 8           <th appDynamicColumnWidth>Name</th>
 9           <th appDynamicColumnWidth>Gender</th>
10           <th appDynamicColumnWidth>Age</th>
11         </tr>
12       </thead>
13       <tbody >
14         <tr *ngFor="let data of ajaxTable.data">
15           <td>{{data.id}}</td>
16           <td>{{data.name}}</td>
17           <td>{{data.gender}}</td>
18           <td>{{data.age}}</td>
19         </tr>
20       </tbody>
21     </nz-table>
22   </div>
23   <div nz-col nzSpan="2">
24 
25   </div>
26 </div>
27 
28 <br><br>

组件ts文件 ,components.component.ts

import { Component, OnInit } from '@angular/core';
import { TableDataService } from '../services/table--data.service';

@Component({
  selector: 'app-components',
  templateUrl: './components.component.html',
  styleUrls: ['./components.component.css']
})
export class ComponentsComponent implements OnInit {

  public tableDatas: Array<Object> = [];

  // 等待动画
  public loading: boolean = false;
  // 分页配置
  public currentPage: number = 1;
  public itemsPerpage: number = 5;
  public totalItems: number = 0;
  constructor(
    private tableDataService:TableDataService
  ) { 
    
  }

  ngOnInit() {
    this.getData();
  }


  getData(){
    // 从服务器查询表格数据
    let result = this.tableDataService.getTableData(this.currentPage,this.itemsPerpage);
    console.log("result:",result);
    this.totalItems = result["totalCounts"];
    this.tableDatas = result["list"];
    
  }
}

封装模拟请求服务器的接口服务,table-data.service.ts 

 1 import { Injectable } from '@angular/core';
 2 
 3 @Injectable({
 4   providedIn: 'root'
 5 })
 6 export class TableDataService {
 7 
 8   constructor() { }
 9 
10   getTableData(currentPage: number, itemsPerpage: number): Object {
11     let totalDatas = [
12       { id: 0, name: "张三", gender: "男", age: 23 },
13       { id: 1, name: "李四", gender: "男", age: 25 },
14       { id: 2, name: "王五", gender: "男", age: 28 },
15       { id: 3, name: "赵六", gender: "男", age: 22 },
16       { id: 4, name: "马七", gender: "男", age: 29 },
17       { id: 5, name: "锅巴", gender: "男", age: 30 },
18       { id: 6, name: "关羽", gender: "男", age: 56 },
19       { id: 7, name: "张飞", gender: "男", age: 28 },
20       { id: 8, name: "刘备", gender: "男", age: 26 },
21       { id: 9, name: "王启年", gender: "男", age: 23 },
22       { id: 10, name: "郭麒麟", gender: "男", age: 28 },
23       { id: 11, name: "陈萍萍", gender: "男", age: 45 },
24       { id: 12, name: "影子", gender: "男", age: 67 },
25       { id: 13, name: "高达", gender: "男", age: 89 },
26       { id: 14, name: "上山虎", gender: "男", age: 24 },
27       { id: 15, name: "海棠朵朵", gender: "男", age: 18 },
28     ]
29 
30 
31     let result = [];
32     let startNumber = (currentPage - 1) * itemsPerpage;
33     let endNumber = (currentPage) * itemsPerpage;
34 
35     totalDatas.map((item, index) => {
36       if ((index >= startNumber) && (index < endNumber)) {
37         result.push(item);
38       } else {
39         // Do-nothing
40       }
41     })
42 
43 
44     return {
45       currentPage: currentPage,
46       itemsPerpage: itemsPerpage,
47       totalCounts: totalDatas.length,
48       list: result,
49     }
50   }
51 }

自定义指令,dynamic-column-width.directivej.ts 

 1 import { Directive, ElementRef, HostListener } from '@angular/core';
 2 
 3 @Directive({
 4   selector: '[appDynamicColumnWidth]'
 5 })
 6 export class DynamicColumnWidthDirective {
 7   public elem = null;
 8   public mouseDown: boolean = false;
 9   public oldX: number = 0;
10   public oldWidth: number = 0;
11   public  number = 0;
12 
13   constructor(private el: ElementRef) {
14     
15   }
16 
17   ngOnInit(): void {
18    
19   }
20 
21   @HostListener('mousedown', ['$event'])
22   onMousedown(e) {
23     // 判断当前点击的是否是单元格元素
24     if (this.el != null) {
25       if (e.offsetX > this.el.nativeElement.offsetWidth - 15) {
26         this.el.nativeElement.mouseDown = true;
27         this.el.nativeElement.oldX = e.x;
28         this.el.nativeElement.oldWidth = this.el.nativeElement.offsetWidth;
29       }
30     } else {
31       // Do-nothing
32     }
33   }
34 
35 
36 
37   @HostListener('mouseup', ['$event'])
38   onMouseup(e) {
39     if (this.el != null) {
40       this.el.nativeElement.mouseDown = false;
41       this.el.nativeElement.style.cursor = 'default';
42     }
43   }
44 
45 
46 
47   @HostListener('mousemove', ['$event'])
48   onMousemove(e) {
49     if(this.el != null){
50       if (e.offsetX > this.el.nativeElement.offsetWidth - 15) {
51         this.el.nativeElement.style.cursor = 'col-resize';
52       } else {
53         this.el.nativeElement.style.cursor = 'default';
54       }
55     }
56 
57     if (this.el.nativeElement.mouseDown != null && this.el.nativeElement.mouseDown == true) {
58       this.el.nativeElement.style.cursor = 'default';
59       let wid = 0;
60       if (this.el.nativeElement.oldWidth + (e.x - this.el.nativeElement.oldX) > 0) {
61         wid = this.el.nativeElement.oldWidth + (e.x - this.el.nativeElement.oldX);
62       }
63       this.el.nativeElement.style.width = wid + 'px';
64       this.el.nativeElement.style.cursor = 'col-resize';
65       // ng-zorro table 列宽可以根据thead每个单元格的宽度自动适配,所以不用再做修改
66     } else {
67       // console.log("无所谓!");
68     }
69   }
70 }

在模块中依赖注入自定义指令,components.module.ts 

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { ComponentsRoutingModule } from './components-routing.module';
import { ComponentsComponent } from './components.component';
import { NgZorroAntdModule } from 'ng-zorro-antd';
import { DynamicColumnWidthDirective } from '../directives/dynamic-column-width.directive';

@NgModule({
  imports: [
    CommonModule,
    ComponentsRoutingModule,
    NgZorroAntdModule.forRoot(),
  ],
  declarations: [ComponentsComponent,DynamicColumnWidthDirective]
})
export class ComponentsModule { }

注意:

自定义指令需要在待使用组件所在模块module文件中引入,如上。
如果存在多个组件都需要使用该自定义指令,请将新建一个公共模块,在公共模块中依赖注入自定义指令,在待使用组件中依赖注入公共模块。

四、运行截图

Angular ng-zorro table拖拽配置列宽-冯金伟博客园

五、源码

  源码请参考 https://github.com/guojije/dynamicColumn