基于 Angular Material 的 Data Grid 设计实现
2020-06-27 22:52
836 查看
![](https://img2020.cnblogs.com/blog/999445/202006/999445-20200627174611906-1272921735.jpg)
> 自 Extensions 组件库发布以来,Data Grid 成为了使用及咨询最多的组件。最开始 Data Grid 的设计非常简陋,经过一番重构,组件质量有了质的提升。
> Extensions 组件库: [https://github.com/ng-matero/extensions](https://github.com/ng-matero/extensions)
> Data Grid 示例: [https://ng-matero.github.io/extensions/data-grid](https://ng-matero.github.io/extensions/data-grid)
距离 Data Gird 重构已经过去了两个多月,因工作忙碌而迟迟没有介绍 Data Grid 的细节。这几天又重构了一下官网示例,目前的 API 文档放在了 [gitbook](https://app.gitbook.com/@nzbin/s/material-extensions/) 上,暂时还没有和官网整合,国内访问会比较慢。本文会介绍 Data Grid 的使用方法及比较好的一些功能实现。说点题外话,**开发一款插件最大的难度不在于功能的实现,而在于如何去设计插件**。
## 什么是 Data Grid?
Data Grid 本质上就是通过 `数据`+`列定义`+`配置项` 来渲染表格的插件。这比写一堆 DOM 结构要简洁很多,可以说是 CRUD 业务中的大杀器之一。目前市面上功能最全的 Data Grid 是 [ag-grid](https://www.ag-grid.com/),很多组件库也有自己的 Data Grid 实现,比如 [Ignite UI](https://www.infragistics.com/products/ignite-ui-angular/angular/components/grid/grid.html),[Kendo UI](https://www.telerik.com/kendo-angular-ui/components/grid/)。但是市面上这些优秀的插件基本都要收费,另外就是遇到变态需求时,第三方插件的功能定制会遇到很多问题,这也是我自研 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(各种模板)
因文章篇幅有限,本文主要介绍一些重点功能,其它功能可以参考官网示例。
### 基本用法
![](https://img2020.cnblogs.com/blog/999445/202006/999445-20200626102718615-789150374.jpg)
> 官网示例:[Basic](https://ng-matero.github.io/extensions/data-grid#basic)
定义组件参数
```html
```
定义数据及列
```ts
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
```js
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
```html
```
权衡各种利弊,Extensions Data Grid 选择了第一种定义方法,接口定义如下:
```ts
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 | null;
showExpand?: boolean;
description?: string;
i18n?: string;
summary?: ((colData: any, colDef?: any) => void) | string;
}
```
### 模板
![](https://img2020.cnblogs.com/blog/999445/202006/999445-20200626111959247-1923183564.jpg)
模板是 angular 组件极其灵活的一个功能。大部分优秀的第三方组件都具有自定义模板的能力,而在 Data Grid 中,模板更是一个不可或缺的功能。Extensions Data Grid 的模板功能已经比较完善,单元格模板除了基本的方法外,还增加了更为简单易用的方法。
#### 普通方法
```html
Slide me!
```
```ts
export class AppComponent implements OnInit {
@ViewChild('statusTpl', { static: true }) statusTpl: TemplateRef;
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](https://ng-matero.github.io/extensions/data-grid#custom-cell-template)
引用模板实例是一种很常见的思路,但是弊端就是必须将列定义写在 ngOnInit 中,而且要先引用所用的自定义模板实例。这种写法很不灵活。
#### 升级方案
```html
{{row.city}}
```
> 官网示例:[Custom cell template 2](https://ng-matero.github.io/extensions/data-grid#custom-cell-template-2)
这种方法直接在组件参数中定义了模板实例,不需要再写其它任何代码,非常简单!
除了单元格模板之外,还有 headerTemplate、summaryTemplate、toolbarTemplate 等,可以满足大部分的个性化需求,详情见官网示例。
### 选取
![](https://img2020.cnblogs.com/blog/999445/202006/999445-20200626103339835-1123168463.jpg)
> 官网示例:[Row selectable](https://ng-matero.github.io/extensions/data-grid#row-selectable)
表格的行选取是一个很常见的需求,用途广泛。默认开启单元格选取,可以设置 `[cellSelectable]="false"` 以关闭单元格选取。
通过 `[rowSelectable]="true"` 可以开启行选取。
```html
```
通过 `[multiSelectable]="true"` 可以设置多选行。这里有一个细节,按住 ctrl 并单击才可以多选,或者直接点击 checkbox 也可以。如果需要隐藏 checkbox,只需要设置 `[hideRowSelectionCheckbox]="true"`。
如果初始化表格时希望默认选中某些行,则只需要定义 `[rowSelected]=[...]`。
#### 不可选取
![](https://img2020.cnblogs.com/blog/999445/202006/999445-20200626110254209-1846383215.jpg)
设置不可选取行的方式有两种,一种是设置 checkbox 为 disabled,另一种是隐藏 checkbox。配置非常简单,只需要通过 `rowSelectionFormatter` 过滤数据即可。
```html
```
```ts
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',
};
}
```
### 行展开
![](https://img2020.cnblogs.com/blog/999445/202006/999445-20200626103402308-1197363292.jpg)
> 官网示例:[Expandable row](https://ng-matero.github.io/extensions/data-grid#expandable-row)
行展开的实现借助了 Angular Material 表格的 `multiTemplateDataRows` 参数,实现细节很多。Data Grid 的代码如下:
设置 `expandable` 和 `expansionTemplate`
```html
{{row.name}}
```
在列定义中设置 `showExpand`, 确定在哪个列显示展开符号。
```ts
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;
}
```
### 列操作
![](https://img2020.cnblogs.com/blog/999445/202006/999445-20200626110405972-517823155.jpg)
> 官网示例:[Column hiding & moving](https://ng-matero.github.io/extensions/data-grid#column-hiding-moving)
列的显示隐藏以及排序是非常常见的需求,这类需求曾被产品经理折磨了无数次。目前的列操作 UI 只有菜单方式,之后还会添加侧边栏的 UI,暂时不支持列的横向拖拽。
列的操作完全可以移到组件之外,通过设置 columns 实现,并不一定非要用 Data Grid 集成好的功能。
## 总结
因篇幅有限,很多 Data Grid 的功能没有详细介绍。从我遇到的需求来看,目前的 Data Grid 已经可以覆盖九成的需求了,还有很多高级功能正在开发当中,欢迎大家提出建设性意见。如果大家在使用组件的过程中遇到问题,可以在 GitHub 中提交 [issues](https://github.com/ng-matero/extensions/issues) 或者进讨论群提问。
相关文章推荐
- 基于ZooKeeper,Spring设计实现的参数系统
- 二、基于Cortex-A8和ZigBee技术的智能家居监控系统的设计与实现
- Windows平台下基于WFP模型的网络防火墙设计实现
- Android HAL实现的三种方式(3) - 基于Manager的HAL设计
- Android Material Design:基于CoordinatorLayout实现向上滚动导航条ToolBar滚出、向下滚动导航条滚出
- 基于NX的研发产品设计管理平台实现(十七)-物料描述自动提取2
- 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获
- 基于Java、Kafka、ElasticSearch的搜索框架的设计与实现
- 基于Java web的学生综合测评管理的设计与实现
- 基于ARM的嵌入式MPEG-4远程网络监控系统的设计与实现
- 设计实现 一个 基于extjs2.0 做皮肤的 struts2 样式
- 基于角色-功能-资源的权限控制模型的设计与实现-引子
- 操作系统课程设计 基于DOS的多任务系统的实现
- 今天又学了一招 基于XMLHTTP 实现表示层的设计
- 基于微信小程序的校园闲置交易平台(跳蚤市场)的设计与实现
- 基于HTML5+CSS3的旅游网站设计与实现
- Android HAL实现的三种方式(3) - 基于Manager的HAL设计
- 重新研读C#语言——《设计模式—基于C#的工程化实现及扩展》
- 基于ZedBoard的Webcam设计(五):x264编码在zedboard上的实现(软编码)
- 基于Android移动终端的微型餐饮管理系统的设计与实现4——Android基础