Install
npm insatll angular-ui-grid
Href
import {grid} from 'angular-ui-grid';
note:默认的exports只有'ui.grid',如需使用其他指令需在index中增加exports的module ;
require('./ui-grid.min.css');
exports.uiGrid = 'ui.grid';
exports.uiGridPagination = 'ui.grid.pagination';
exports.uiGridResizeColumns = 'ui.grid.resizeColumns';
Module
angular.module('ui.grid', [grid.uiGrid, grid.uiGridPagination, grid.uiGridResizeColumns, grid.uiGridMoveColumns, grid.uiGridSelection, grid.uiGridPinning...])
Use
1、basic
<div class="grid" ui-grid="$ctrl.gridOptions" ui-grid-pagination></div>
class controller{
constructor(i18nService,$timeout){
this.i18nService = i18nService;
this.$timeout = $timeout;
}
$onInit(){
this.i18nService.setCurrentLang('zh-cn'); //汉化
this.gridOptions = {
enableSorting: true, //是否sort
enableFiltering: true, //是否filter
enableCellEdit: true, //是否可以编辑
enableGridMenu: true, //是否显示下拉按钮
enablePagination: true,
enablePaginationControls: true, //是否显示分页
enableFullRowSelection: true,
enableSelectAll: false, //是否可以全选
enableRowHeaderSelection: false,
multiSelect: false, // 是否多选
columnDefs:[], //列属性配置
data:[] //数据源
};
}
}
note:值得注意的几个columnDefs有sort、filter、celltemplate、cellTooltip
简单说下cellTooltip吧,鼠标悬浮时显示全部内容
如果该td有filter处理数据时,cellTooltip设置为true即可
如果自己定义
cellTooltip:(row,col)=>{
//返回的行数据和列配置
return ``;
}
2、pagination
<div class="grid" ui-grid="$ctrl.gridOptions" ui-grid-pagination></div>
this.gridOptions = {
enablePagination:true,
enablePaginationControls: true, //是否显示分页
paginationPageSizes: [10, 20, 30, 50], //每页显示数据条数
columnDefs:[], //列属性配置
};
对于多数时候而言,服务器返回的数据是带有分页信息的,那么如何将grid的分页和数据的分页结合? 在gridOptions中,有一个叫做onRegisterApi的callback,return gridApi(grid的实例化)
this.gridOptions = {
onRegisterApi:(gridApi) => {
this.gridApi = gridApi;
this.gridApi.pagination.on.paginationChanged(null, (newPage, pageSize) => {
this.getData(newPage, pageSize); //一般请求只用传入page和pageSize
});
}
};
注意:由于onRegisterApi返回的grid的实例,所以gridApi需绑到外层作用域,这里使用箭头函数(箭头函数没有自己的this,会继承外部的this,不用再像ES5中写var this=that或者bind(),
翻页和输入页数时,都会返回新的页面数newPage和每页数量pageSize,因此在返回数据绑定到gridOptions时,需要记录下总数、当前页和每页数据量
this.gridOptions.data = result.data;
this.gridOptions.totalItems = result.pagination.amount;
this.gridOptions.paginationCurrentPage = result.pagination.current_page;
this.gridOptions.paginationPageSize = result.pagination.nun_per_page;
3、sort
grid自带了排序,但是是基于当前页的排序,可能很多时候是不符合需求的,那么同理,同样有sortChanged事件,其中返回的sortColumns是已经排序的列的数组
<div class="grid" ui-grid="$ctrl.gridOptions" ui-grid-sort></div>
this.gridApi.core.on.sortChanged(null, (grid, sortColumns) => {
// 根据后台需要的排序参数,处理sort对象
this.getData(currentpage, pageSize, sort, filter);
});
4、filter
grid的filter也是基于当前页进行过滤,支持输入,选择,时间,两个值之间过滤...具体配置方法见doc_filter
filterChanged中不同的是,没有返回每一列的过滤值,但是我们可以在gridApi.grid.columns中找到filters数组
<div class="grid" ui-grid="$ctrl.gridOptions" ui-grid-filter></div>
this.gridApi.core.on.filterChanged(null, () => {
let filter = {};
angular.forEach(this.gridApi.grid.columns, (column) => {
column.filters && column.filters.length && (filter[column.field] = column.filters[0].term);
});
// 可以在调用getData()时加上$timeout,延迟500ms后执行
});
5、resizeColumns
直接写上指令,引入module即可
6、moveColumns
同上,如需限制宽度,在所需列中设置minWidth和maxWidth即可
7、selection
selection拥有选中状态,由于后台不支持多行操作,选取事件rowSelectionChanged,返回row
<div class="grid" ui-grid="$ctrl.gridOptions" ui-grid-filter></div>
this.gridApi.selection.on.rowSelectionChanged(null, (row) => {
console.log(row);
// 这里可以获取选中行数据,进行删除、修改等操作
});
8、pinning
即可以设置固定列,如横向滚动时,最后一列始终在原位保持不变
<div class="grid" ui-grid="$ctrl.gridOptions" ui-grid-filter></div>
this.gridOptions = {
columnDefs:[
{
name: 'name',
displayName: '姓名',
pinnedLeft: true
},
{
name: 'sex',
displayName: '姓别'
},
{
name: 'age',
displayName: '年龄'
}
]
}
pinnedLeft:true该列将固定于左边
pinnedRight:true该列将固定于右边
9、edit
默认双击时可以直接在表格进行编辑,官方提供了很多行内编辑样式,输入框、单选、下拉框、时间选择器等...如果要使用grid自带edit的朋友可以直接看官方文档edit
edit时有两个事件,分别是编辑前(beginCellEdit)和编辑后(afterCellEdit)
this.gridApi.edit.on.beginCellEdit(null, (rowEntity, colDef, event) => {
// rowEntity每行数据 colDef每列配置
// 可以进行edit初始化等操作
});
若使用其他插件进行edit,则主要依赖cellTemplate和editableCellTemplate,这里用multi-select插件进行说明
很多时候下拉选择框后台通常存储id,因此返回的数据中只有id,但是我们在进行表格展示的时候,则需要使用它对应的name,所以可以配置cellTemplate模板,使用filter等,末班中取值通常使用row.entity.(columnDefs中绑定的key),下拉选择时配置的value数组是配置在editDropdownOptionsArray中
如下:getDictNameById是初始化表格时展示name的filter
this.gridOptions = {
columnDefs:[
{
name:'material_id',
displayName:'原料名称',
editDropdownOptionsArray:[id:1,name:'xxx'...........],
cellTemplate: '<div class="ui-grid-cell-contents">{{row.entity.materialArr?(row.entity.materialArr|getNameByChooseArray):(row.entity.material_name_id|getDictNameById:col.colDef.editDropdownOptionsArray)}}</div>',
editableCellTemplate: '<ui-grid-edit-multi><div isteven-multi-select input-model="col.colDef.editDropdownOptionsArray" output-model="row.entity.materialArr" button-label="name" item-label="id name" tick-property="selected" selection-mode="single" ng-required="true"></div></ui-grid-edit-multi>',
}
]
}
自己配置edit时会发现,输入后无法取消编辑状态,如何把编辑后的值展示在表格上
如上所示getNameByChooseArray则是下拉选择编辑会后展示的filter,我们查看官方的edit模板可知,每次完成编辑时,
需要通知grid编辑完成uiGridEditConstants.events.END_CELL_EDIT,因此我们可以自定义指令
export function UiGridEditMultiDirective($document, uiGridEditConstants) {
return {
link($scope, $elm, $attr) {
$document.on('click', docClick);
function docClick(evt) {
if ($elm[0].innerHTML.indexOf('checkboxLayer show') === -1) {
$scope.$emit(uiGridEditConstants.events.END_CELL_EDIT);
$document.off('click', docClick);
}
}
}
}
}
UiGridEditMultiDirective.$inject = ['$document', 'uiGridEditConstants'];
简单的行内编辑使用很方便,但是操作复杂时,配置会相当麻烦
10、exporter
直接使用指令就可以使用(导出pdf和csv两种文件),可以配置header、footer、style等,详见文档exporter
导出的文件导出的是数据源的data,但是我们可以利用exporterFieldCallback来更改你的数据
11、设置noData和loading
<div ui-grid="$ctrl.gridOptions" ui-grid-pagination ui-grid-resize-columns ui-grid-move-columns ui-grid-selection
ui-grid-pinning class="grid">
<div class="grid-msg" ng-if="$ctrl.noData">
<div class="no-data">
<i class="fa fa-warning"></i>
<span>暂无匹配数据</span>
</div>
</div>
</div>
.grid-msg {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
background: rgba(0, 0, 0, 0.4);
z-index: 1000;
.no-data {
position: absolute;
top: 25%;
left: 25%;
width: 50%;
height: 50%;
background-color: #eee;
border-radius: 4px;
border: 1px solid #eee;
text-align: center;
font-size: 24px;
display: table;
padding-top: 100px;
i {
color: #F48319;
}
}
}
//只有在使用结束时设置noData即可
this.noData = !result.data.length;
loading同理,在返回data时将loading的显示设置为false即可