Angular ng-zorro table拖拽配置列宽

一、技术框架及版本

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

二、前提

  1. 搭建Angular环境
  2. 在Angular项目中引入ng-zorro
  3. 创建一个自定义指令,用于监听鼠标事件
  4. 在要监听的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文件中引入,如上。
  • 如果存在多个组件都需要使用该自定义指令,请将新建一个公共模块,在公共模块中依赖注入自定义指令,在待使用组件中依赖注入公共模块。

四、运行截图

五、源码

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

原文地址:https://www.cnblogs.com/mycnblogs-guoguo/p/12119111.html