基于 Angular Material 的 Data Grid 设计实现

栏目: IT技术 · 发布时间: 4年前

内容简介:自 Extensions 组件库发布以来,Data Grid 成为了使用及咨询最多的组件。最开始 Data Grid 的设计非常简陋,经过一番重构,组件质量有了质的提升。Extensions 组件库:

基于 Angular Material 的 Data Grid 设计实现

自 Extensions 组件库发布以来,Data Grid 成为了使用及咨询最多的组件。最开始 Data Grid 的设计非常简陋,经过一番重构,组件质量有了质的提升。

Extensions 组件库: https://github.com/ng-matero/extensions

Data Grid 示例: https://ng-matero.github.io/extensions/data-grid

距离 Data Gird 重构已经过去了两个多月,因工作忙碌而迟迟没有介绍 Data Grid 的细节。这几天又重构了一下官网示例,目前的 API 文档放在了 gitbook 上,暂时还没有和官网整合,国内访问会比较慢。本文会介绍 Data Grid 的使用方法及比较好的一些功能实现。说点题外话, 开发一款插件最大的难度不在于功能的实现,而在于如何去设计插件

什么是 Data Grid?

Data Grid 本质上就是通过 数据 + 列定义 + 配置项 来渲染表格的插件。这比写一堆 DOM 结构要简洁很多,可以说是 CRUD 业务中的大杀器之一。目前市面上功能最全的 Data Grid 是 ag-grid ,很多组件库也有自己的 Data Grid 实现,比如 Ignite UIKendo UI 。但是市面上这些优秀的插件基本都要收费,另外就是遇到变态需求时,第三方插件的功能定制会遇到很多问题,这也是我自研 Data Grid 的初衷。

Angular Material 对于 table 的封装已经足够灵活,但是模板的定义依然很繁琐,也缺少很多刚需功能。Data Grid 几乎整合了 Angular Material 表格的所有功能,同时又增加了很多实用功能。

Extensions Data Grid 简介

Extensions Data Grid 的功能实现参考了 ag-grid 以及其它插件,重构时对变量及参数命名进行了很细致的考究。目前 Data Grid 已经实现的功能如下:

  • paging(分页,包括前端分页和后端分页)
  • sorting(排序,目前只支持单一排序)
  • sticky columns(列的固定)
  • column hiding(列的显示隐藏)
  • checkbox selection(数据选择)
  • row selection(行选取,可多选)
  • cell selection(单元格选取,暂时支持单选)
  • expandable row(可展开的表格行)
  • customized cell(自定义单元格)
  • column moving(列的移动排序)
  • Data Formatting(数据格式化)
  • Template(各种模板)

因文章篇幅有限,本文主要介绍一些重点功能,其它功能可以参考官网示例。

基本用法

基于 Angular Material 的 Data Grid 设计实现

官网示例: Basic

定义组件参数

<mtx-grid [data]="list" 
          [columns]="columns">
</mtx-grid>

定义数据及列

export class AppComponent {
  columns: MtxGridColumn[] = [
    { header: 'Name', field: 'name' },
    { header: 'Weight', field: 'weight' },
    { header: 'Gender', field: 'gender' },
    { header: 'Mobile', field: 'mobile' },
    { header: 'City', field: 'city' },
  ];

  list = EXAMPLE_DATA;
}

补充介绍一下,市面上 Data Grid 定义列的方式主要有两种:

1、JS 定义,比如 ag-grid

var gridOptions = {
    // define 3 columns
    columnDefs: [
        { headerName: 'Athlete', field: 'athlete' },
        { headerName: 'Sport', field: 'sport' },
        { headerName: 'Age', field: 'age' }
    ],

    // other grid options here...
}

2、模板定义,比如 Ignite UI

<igx-grid igxPreventDocumentScroll #grid1 [data]="data | async" [height]="'500px'" width="100%" [autoGenerate]='false' [allowFiltering]="true">
    <igx-column [field]="'Category'" [width]="'120px'"></igx-column>
    <igx-column [field]="'Type'" [width]="'150px'" [filterable]='false'></igx-column>
    <igx-column [field]="'Open Price'" [width]="'120px'" dataType="number" [formatter]="formatCurrency">
    </igx-column>
    <igx-column [field]="'Price'" [width]="'120px'" dataType="number" [formatter]="formatCurrency"></igx-column>
</igx-grid>

权衡各种利弊,Extensions Data Grid 选择了第一种定义方法,接口定义如下:

export interface MtxGridColumn {
  field: string;
  header?: string;
  hide?: boolean;
  disabled?: boolean;
  pinned?: 'left' | 'right';
  left?: string;
  right?: string;
  width?: string;
  resizable?: boolean;
  sortable?: boolean | string;
  type?: 'tag' | 'button' | 'link' | 'image' | 'number' | 'currency' | 'percent' | 'boolean';
  tag?: MtxGridColumnTag;
  buttons?: MtxGridColumnButton[];
  formatter?: (rowData: any, colDef?: any) => void;
  cellTemplate?: TemplateRef<any> | null;
  showExpand?: boolean;
  description?: string;
  i18n?: string;
  summary?: ((colData: any, colDef?: any) => void) | string;
}

模板

基于 Angular Material 的 Data Grid 设计实现

模板是 angular 组件极其灵活的一个功能。大部分优秀的第三方组件都具有自定义模板的能力,而在 Data Grid 中,模板更是一个不可或缺的功能。Extensions Data Grid 的模板功能已经比较完善,单元格模板除了基本的方法外,还增加了更为简单易用的方法。

普通方法

<mtx-grid [data]="list"
          [columns]="columns">
</mtx-grid>

<ng-template #statusTpl let-row let-index="index" let-col="colDef">
  <mat-slide-toggle [checked]="row.status">Slide me!</mat-slide-toggle>
</ng-template>
export class AppComponent implements OnInit {
  @ViewChild('statusTpl', { static: true }) statusTpl: TemplateRef<any>;

  columns: MtxGridColumn[] = [];

  list = EXAMPLE_DATA;

  ngOnInit() {
    this.columns = [
      { header: 'Name', field: 'name' },
      { header: 'Weight', field: 'weight' },
      { header: 'Gender', field: 'gender' },
      { header: 'Mobile', field: 'mobile' },
      { header: 'City', field: 'city' },
      { header: 'Status', field: 'status', cellTemplate: this.statusTpl },
    ];
  }
}

官网示例: Custom cell template

引用模板实例是一种很常见的思路,但是弊端就是必须将列定义写在 ngOnInit 中,而且要先引用所用的自定义模板实例。这种写法很不灵活。

升级方案

<mtx-grid [data]="list"
          [columns]="columns"
          [cellTemplate]="{ city: cityTpl }">
</mtx-grid>

<ng-template #cityTpl let-row let-index="index" let-col="colDef">
  <button mat-raised-button color="primary">{{row.city}}</button>
</ng-template>

官网示例: Custom cell template 2

这种方法直接在组件参数中定义了模板实例,不需要再写其它任何代码,非常简单!

除了单元格模板之外,还有 headerTemplate、summaryTemplate、toolbarTemplate 等,可以满足大部分的个性化需求,详情见官网示例。

选取

基于 Angular Material 的 Data Grid 设计实现

官网示例: Row selectable

表格的行选取是一个很常见的需求,用途广泛。默认开启单元格选取,可以设置 [cellSelectable]="false" 以关闭单元格选取。

通过 [rowSelectable]="true" 可以开启行选取。

<mtx-grid [data]="list"
          [columns]="columns"
          [rowSelectable]="rowSelectable"
          (rowSelectionChange)="log($event)"
          (cellSelectionChange)="log($event)">
</mtx-grid>

通过 [multiSelectable]="true" 可以设置多选行。这里有一个细节,按住 ctrl 并单击才可以多选,或者直接点击 checkbox 也可以。如果需要隐藏 checkbox,只需要设置 [hideRowSelectionCheckbox]="true"

如果初始化表格时希望默认选中某些行,则只需要定义 [rowSelected]=[...]

不可选取

基于 Angular Material 的 Data Grid 设计实现

设置不可选取行的方式有两种,一种是设置 checkbox 为 disabled,另一种是隐藏 checkbox。配置非常简单,只需要通过 rowSelectionFormatter 过滤数据即可。

<mtx-grid [data]="list"
          [columns]="columns"
          [rowSelectable]="true"
          [rowSelectionFormatter]="rowSelectionFormatter">
</mtx-grid>
export class AppComponent {
  columns: MtxGridColumn[] = [
    { header: 'Name', field: 'name' },
    { header: 'Weight', field: 'weight' },
    { header: 'Gender', field: 'gender' },
    { header: 'Mobile', field: 'mobile' },
    { header: 'City', field: 'city' },
  ];

  list = EXAMPLE_DATA;

  rowSelectionFormatter: MtxGridRowSelectionFormatter = {
    disabled: (data) => data.name === 'Boron',
    hideCheckbox: (data) => data.name === 'Helium',
  };
}

行展开

基于 Angular Material 的 Data Grid 设计实现

官网示例: Expandable row

行展开的实现借助了 Angular Material 表格的 multiTemplateDataRows 参数,实现细节很多。Data Grid 的代码如下:

设置 expandableexpansionTemplate

<mtx-grid [data]="list"
          [columns]="columns"
          [expandable]="true"
          [expansionTemplate]="expansionTpl">
</mtx-grid>

<ng-template #expansionTpl let-row>
  {{row.name}}
</ng-template>

在列定义中设置 showExpand , 确定在哪个列显示展开符号。

export class AppComponent {
  columns: MtxGridColumn[] = [
    { header: 'Name', field: 'name', showExpand: true },
    { header: 'Weight', field: 'weight' },
    { header: 'Gender', field: 'gender' },
    { header: 'Mobile', field: 'mobile' },
    { header: 'City', field: 'city' },
  ];

  list = EXAMPLE_DATA;
}

列操作

基于 Angular Material 的 Data Grid 设计实现

官网示例: Column hiding & moving

列的显示隐藏以及 排序 是非常常见的需求,这类需求曾被产品经理折磨了无数次。目前的列操作 UI 只有菜单方式,之后还会添加侧边栏的 UI,暂时不支持列的横向拖拽。

列的操作完全可以移到组件之外,通过设置 columns 实现,并不一定非要用 Data Grid 集成好的功能。

总结

因篇幅有限,很多 Data Grid 的功能没有详细介绍。从我遇到的需求来看,目前的 Data Grid 已经可以覆盖九成的需求了,还有很多高级功能正在开发当中,欢迎大家提出建设性意见。如果大家在使用组件的过程中遇到问题,可以在 GitHub 中提交 issues 或者进讨论群提问。

基于 Angular Material 的 Data Grid 设计实现


以上所述就是小编给大家介绍的《基于 Angular Material 的 Data Grid 设计实现》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Lighttpd

Lighttpd

Andre Bogus / Packt Publishing / 2008-10 / 39.99

This is your fast guide to getting started and getting inside the Lighttpd web server. Written from a developer's perspective, this book helps you understand Lighttpd, and get it set up as securely an......一起来看看 《Lighttpd》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具