上一篇写的是封装了dialog,那么这一篇就来看看datagrid如何封装吧。
我希望最终是这样使用的
html
<table id="dg"></table>
js
// 定义(此时还未进行渲染)(一个选择器,一个参数配置)
var datagrid = new hm.datagrid('#dg',{
rownumbers:true,
columns:[[]],
data:[]
});
// 初始化(渲染)
datagrid.init();
// 调用方法(此方法会先执行init(),所以除非必要是不需要手动调用init()方法的)
datagrid.invoke('appendRow',{});
为什么我会想到要这样封装
项目里碰到这样的需求,有一张表格是用来录入的,录入完成后直接将表格所有数据一次性提交,这里就要求某个字段不能重复。
首先明确这肯定是在添加数据之前进行判断,这里我都是调用appendRow
进行行添加的,那就在我调用这句代码之前判断咯。
确实这是一种很普遍的做法吧,后来我又想,有没有对应的事件呢?在调用appendRow
的时候会先触发该事件,如果返回false
则不执行appendRow
然而并没有。
我突然觉得这个可以有!!
如果有这个事件,那我判断是否重复就写在该事件里,不符合条件的行就return false
不让它添加。因为我这里appendRow
只有一处倒是无所谓,万一还有别的地方也有appendRow
呢,难道再判断一次?
完整代码 datagrid.js
说是完整代码,其实这里我只是提取出来最基本的代码,还可以自己扩展参数什么的
(function () {
'use strict';
// selector 选择器
// options 参数
function datagrid(selector, options) {
// 方便给datagrid.methods里面的方法获取到引用
var target = {
datagrid: null,
options: null
};
return {
init: function () {
if (null === target.datagrid) {
target.options = $.extend({}, datagrid.defaults, datagrid.events, options);
target.datagrid = $(selector).datagrid(target.options);
}
return this;
},
// 原本所有需要调用datagrid方法全部改为此方法
invoke: function (method, params) {
var result;
// 确保已经初始化了
this.init();
if (datagrid.methods[method]) {
result = datagrid.methods[method].call(target, params);
} else {
result = target.datagrid.datagrid(method, params);
}
// 这一句为了达到链式调用的效果
if (result === target.datagrid) { return this; }
return result;
}
}
}
datagrid.defaults = {
singleSelect: true,
rownumbers: true
};
datagrid.events = {
onBeforeAppendRow: function (row) { },
onAfterAppendRow: function (row) { }
};
datagrid.methods = {
// 重写appendRow方法,添加了两个事件。
appendRow: function (row) {
// 如果返回false,取消本次添加
if (false === this.options.onBeforeAppendRow.call(this.datagrid, row)) { return; }
this.datagrid.datagrid('appendRow', row);
this.options.onAfterAppendRow.call(this.datagrid, row);
}
};
window.hm.datagrid = datagrid;
})();
总结
封装之后就会感觉一切都掌握在自己手里啊。
问题
可以看到我将参数、事件、方法都分开来写了,我当然是想能够很好的分离代码。
但我在想一个无聊的问题,比如我想要在单击行的时候显示行坐标,那自然是这样
datagrid.events = {
...
onClickRow: function(index,row) {
console.log(index);
}
...
}
确实这样可以,但如果具体某一个表格也定义了onClickRow的话,这个就被覆盖掉了,我想要的是如何能保证绝对执行。
如果在datagrid
函数内部添加的话,是可以做到的。
function datagrid(selector,options){
...
return {
init: function() {
...
if (null === target.datagrid) {
target.options = $.extend({}, datagrid.defaults, datagrid.events, options);
target.options.onClickRow = function(index, row) {
// 这里是我想要的操作
console.log(index);
// 这里判断是否自定义了该事件
if(options.onClickRow) {
options.onClickRow.call(this,index,row);
}
}
target.datagrid = $(selector).datagrid(target.options);
}
return this;
}
}
}
但我想把这个事件分离出来,就写在 datagrid.events下面,这就是头疼的问题了。