例子中行按钮的用着很别扭,绘制和事件是分离的,我改了一下封装了一个下,代码放上,可以直接拿走,自己扩展,看注释就能会,不会的问我
Index.cshtml
先看写法,再看实现,前台写法,正常列的写法,扩展了一个属性,也是传入绘制的js:
绘制的js,可以看到绘制和事件是连续的,也可以控制权限:
/*绘制btns, * 前两个参数与api一样 * {v} 第一个参数是cell的值,注意先要有DataField属性,这里的v是性别; * {p} 第二个参数是该行的对象,比如 rowId,columnId,rowValue等,自己可以打印出来看看; * {m} 第三个参数是扩展出的参数,为模板列模板绘制方法,目前只封装了按钮的模板,也可以自己封装别的; * {return string/model}可以返回模板,也可以直接返回string的html */ function renderBtns(v, p, m) { //返回按钮的模板,如果多个时按钮返回数组即可 return m.btn([{ text: "编辑", id: 'edit', //点击事件 click() { notifyEx("编辑" + p.rowId); }, //按权限返回false beforRender(t) { if (v == 1) { //返回false 则不绘制 return false; } } },{ text: "删除", id: 'del', //点击事件 click() { if (v == 1) { notifyEx("删除" + p.rowId); } }, //按权限返回false //参数t就是当前按钮的对象,可以对t.el进行操作,是一个jqDOM beforRender(t) { if (v != 1) { //对t进行绘制,比如新增样式 t.el.addClass("f-state-disabled"); } } }]); }
实现
先看扩展的RendererFunctionEx方法,
/// <summary> /// 绘制回调方法 参数为JS名称 /// </summary> /// <param name="f"></param> /// <param name="fn"></param> /// <returns></returns> public static RenderFieldExtension RendererFunctionEx(this RenderFieldExtension f, string fn) { f.RendererFunction("renderEx("+fn+")"); return f; }
核心是renderEx方法,再现保姆级注释
//返回组装后的函数 renderEx = function (fn) { //创建模板 let model = { //按钮模板 btn(opt) { const _btn = (_opt = opt) => { //按钮和text 默认 是value _opt.id = `${_opt.id}_${this.params.rowId}_${this.params.columnId}`; _opt.text = _opt.text || this.value; //绘制按钮 _opt.el = $(`<a id="${_opt.id}">`).addClass("f-btn f-state-default").append(`<span>${_opt.text}</span>`); //触发绘制前方法 let b = _opt.beforRender && _opt.beforRender.apply(this, [_opt]); //注册按钮事件 注意由于还没有绘制所以只能延迟 _opt.click && setTimeout(() => { //可以自己加入其他事件 $('#' + _opt.id).on('click', function () { doCallback(_opt.click, [_opt]); }) }, 0); //返回html if (b || F.isEMP(b)) { return _opt.el[0].outerHTML; } else {//如果绘制的方法回发fasle就没有html return ""; } } //如果不是数组 if (!F.isARR(opt)) { return _btn(); } else { //如果是数组 加入到组里 加个间距的样式 let btndiv = $('<div class="GridRowBtns">'); opt.forEach(item => { btndiv.append(_btn(item)); }) //返回html return btndiv[0].outerHTML; } } } /*柯里化 * 最后还是返回一个方法, * 这个方法将被正常的RendererFunction执行, * 但是扩展了一个参数 * 懂的都懂 * */ return (value, params) => { //先给model赋值 Object.assign(model, { value, params }); //在本示例中触发的是renderBtns方法 自己缕一缕, return doCallback(fn, [value, params, model]); } //apply的写法 //doCallback = function (fn, args) { // return fn.apply(this, args); //} }
还有一个按钮的样式
.GridRowBtns > a:not(:first-child) { margin-left: 5px; } .GridRowBtns > a:hover { box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04); }
本文作者:没想好
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!