了解 Angularjs UI-Grid
起因:项目需要一个可以固定列和表头的表格,因为表格要显示很多列,当水平滚动条拉至后边时可能无法看到前边的某些信息。
以前在angularjs 1.x 中一直都是直接 ng-repeat去完成一个table,显示上没有太多要求,此时遇到这个需求 ,时间上又无法允许你去思考实现之法,而且angularjs 去实现一个像这样的指令也并不容易,于是便要去寻找一个可用的angularjs 插件。
Angular UI-Grid ui-grid.info
同以往的js插件一样,可以通过 bower ,npm 等 获取。
使用 UI-Grid
UI-Grid 公共配置
UI-Grid 使用了一些directive 去实现相应的功能 :
ui-grid-exporter 用于数据导出
ui-grid-pagination 用于启用分页
ui-grid-grouping 用于启用数据分组
ui-grid-selection 用于启用选择行
ui-grid-auto-resize 用于启用高度自适应
ui-grid-pinning 用于固定列
ui-grid-resize-columns 用于拖动列宽度
那么要用到这些指令我们需要将一写Module导入到自己的应用中.在我的app.js 中:
angular.module('exampleApp', [
'ui.grid',
'ui.grid.pinning',
'ui.grid.pagination',
'ui.grid.selection',
'ui.grid.autoResize',
'ui.grid.resizeColumns',
'ui.grid.exporter',
'ui.grid.grouping'
]);
导入之后还需要对grid 进行一些配置
就是上边的 gridOptions ,在我的controller中对它进行如下配置:
UI-Grid Grid配置
exporterMenuCsv:是否在Grid Meun中显示Csv导出项,当启用数据导出时,此配置默认为 true
gridMenuCustomItems:在Grid Menu中我们可以自定义自己的菜单项和对应的行为。
[
{
title: '倒显↙▼↙',
action: function ($event) {
this.grid.element.toggleClass('rotated');
},
order: 211
},{
title: '导出Excel',
action: function ($event) {
var bdate = vm.startDate.val?moment(vm.startDate.val).format('YYYY-MM-DD'):'';
var edate = vm.endDate.val ?moment(vm.endDate.val).format('YYYY-MM-DD'):'';
var status = vm.selectedStatu.status;
var dtype = vm.querySummaryInput.dateType;
var lessexporturi = '/ConnBridge/ExportExcel4lessdata?begindate='+bdate+'&enddate='
abp.openwin(lessexporturi);
},
order: 210
}
]
exporterMenuPdf :是否在Grid Menu 中显示 导出Pdf的选项 ,在启用Pdf的时候需要一些其他的操作,下边在说。
enablePagination:是否启用默认分页,默认为 true
enablePaginationControls:使用底部的默认分页.
paginationPageSizes:页容量的可选值
paginationCurrentPage:页码
paginationPageSize:页容量
totalItems:数据总条数
useExternalPagination:是否使用分页按钮
exporterFieldCallback:导出数据之前的操作,可以进行导出数据格式化
enableGridMenu:是否启用Grid Menu
exporterOlderExcelCompatibility:兼容Excel的Csv操作 ,后边说详细
showGridFooter:是否显示Grid Footer
showColumnFooter:是否显示Column Footer
enableRowHeaderSelection:是否显示选择行的第一列
exporterCsvFilename:需要导出的Csv的文件名称.
exporterPdfDefaultStyle:需要导出的Pdf的默认样式.
exporterPdfFilename:需要导出的Pdf的文件名称.
exporterAllDataFn:当点击导出所有数据时提供数据的方法.
enableHorizontalScrollbar:是否显示水平滚动条. 0 为不显示 1为显示
enableVerticalScrollbar:是否显示垂直滚动条. 0 为不显示 1为显示
onRegisterApi:分页按钮事件方法
UI-Grid Grid Column配置
name:可以用来和数据进行关联,如果不提供应该提供 field以用来让UI-Grid关联数据
field:可以用来和数据进行关联 field以用来让UI-Grid关联数据,和name的具体区别可以看Grid 文档
displayName:显示的列名称
width:指定列宽度 可以用 * 或者** 自动适应 详见文档
rowHeight:行高度,默认是30
enablePinning:启用固定列
pinnedLeft:固定到左侧
pinnedRight:固定到右侧
groupingShowAggregationMenu:是否在菜单中显示分组计算
groupingShowGroupingMenu:是否在列表菜单中显示分组
enableSorting:是否启用排序
visible:是否隐藏列
cellFilter:列数据过滤器 可以应用 date,number ...还有自定义的filter
aggregationType:分组数据显示类型 这里可以计算总和,求平均值等 例如求和: uiGridConstants.aggregationTypes.sum并显示在footer对应的column中
footerCellTemplate:可以自定义column footer的显示模板
type:指定数据类型 应用于排序
UI-Grid Grid 细节
在使用JS插件的时候,常常要考虑的问题是本地化,UI-Grid也不例外
在第一次未配置时候,或显示乱码 ,我们可以注入 i18nService服务来进行获取或配置语言
i18nService.getAllLangs()可以获取所有支持的语言.
i18nService.getCurrentLang()可以查看当前的语言.
这样我们可以通过i18nService.setCurrentLang('zh-cn')可以设置为中文简体
在使用Pdf导出的前提是要引入 pdfmake.min.js 和 vfs_fonts.js
但是当我导出这些数据的时候pdf会中文乱码
解决办法是重新生成 vfs_fonts.js 目的是把中文字体写入此文件
首先我们要找到源代码
mkdir mkpdf cd mkpdf git clone https://github.com/bpampuch/pdfmake.git
pdfmake下的examples中进入fonts文件夹,将我们的中文字体放入此文件夹中。
回到pdfmake文件夹,执行 npm install 确保所有依赖的包都已经安装
之后 执行gulp buildFonts 生成 vfs_fonts.js 和(pdfmake.min.js pdfmake.js )
完成这些之后我们要做的是,将自己项目中的这些js文件 替换为 新生成的js文件。
在我们要导出pdf之前还要配置一下字体
window.pdfMake.fonts={
simblack: {
normal: 'msyh.ttf',
bold: 'msyhbd.ttf',
italics: 'msyh.ttf',
bolditalics: 'msyh.ttf'
},
Roboto: {
normal: 'Roboto-Regular.ttf',
bold: 'Roboto-Medium.ttf',
italics: 'Roboto-Italic.ttf',
bolditalics: 'Roboto-Italic.ttf'
}
}
这样我们就可以在UI-Grid中配置我们想要使用的预定义字体 ,还记得上边这个配置么 ?
exporterPdfDefaultStyle :{font:'simblack',fontSize: 9}
导出的Csv文件,Excel 打开乱码
开发的时候因为本机一直安装wps 所以打开一直没问题,可是拿到别人的机器上用 office excel 2016 打开中文就会乱码.
这个乱码多是编码问题,这样我用记事本打开指定的Csv文件并用 ANSI 编码 替换,中文便可以正常显示
github 上找到这个问题 他们可以用这个属性配置兼容 office excel 正确显示中文 就是上边提到的 这个配置 exporterOlderExcelCompatibility:true 这个配置默认是 false 的,需要我们自己启用。
虽然 用 office excel 2016 打开不会乱码了,但是我用 office excel 2007 打开问题依旧, 看样子Csv文件做表格并不妥当.
后来 我干脆把前台的数据导出都移至后台,于是就出现了为什么要自定义Grid Menu 的需要 还有就是禁用菜单默认显示的Csv文件导出。
Grid 虽好很多功能都实现的不错,但是自己用的时候发现一些问题 :
1 . 当我开启固定列时,如果没有水平滚动条的话,那么当垂直滚动数据到底部的时候固定列的数据和后边的数据行会对不齐。
2 . 当快速拉动滚动条(垂直或水平)时,表格会卡顿,数据显示并不是十分流畅,这点我感觉是 UI-Grid 最悲催的问题,或许是我看问题的视角不够广,但是问题毕竟是问题。
当需要自定义Column Footer cell 的样式和数据时 在 footerCellTemplate 中我们可以 用 grid.appScope 访问 $scope 可以用 row 和 grid 去找我们想要的行 或者是grid 数据。
比如我之前的要的一个功能是在分组的那一行显示一个按钮用于跳转 详细页面 ,那么首先我要确定 哪一行是 分组行,还要找到那一行"分组的文本"(例如按订单编号分组,分组文本就是订单编号) 。
1 .确定是不是分组那一行(或是聚合的那一行) 我们可以用 row.groupHeader===true 。
2. 找到分组文本(或是聚合文本) ,可以用 row.entity['$$uiGrid-0008'].groupVal 。
补充:
对于上边的表格卡顿问题,之前没有仔细阅读文档,在Grid-Options 的配置中可以用 columnVirtualizationThreshold :10 (列)和virtualizationThreshold:20(行) 这两个配置解决 ,我们可以将他们的值设置的大一些,就不会卡顿了。 O(∩_∩)O~~