EasyUI+Knockout实现经典表单的查看、编辑

此文章是基于  搭建Jquery+SpringMVC+Spring+Hibernate+MySQL平台

一. 准备工作

  1. 点击此下载 ims.rar,解压缩并把文件放到 ims 工程对应的文件夹下

二. 前端框架特色

  1. js库为 jquery-1.8.1.min.js

  2. UI选用 jquery-easyui-1.3.2

  3. 封装了一大部分比较实用的控件和组件,如自动完成控件、弹出控件、日期控件等

  4. 选 knockoutjs 为前端mvvm框架

    采用Knockout,提供了一个数据模型与用户UI界面进行关联的高层次方式(采用行为驱动开发)

  5. css框架选用 960gssexybuttons、css3 btn

三. 相关文件介绍

  1. jquery.easyui.fix.js

/**
* 模块名:easyui方法修改
* 程序名: easyui.fix.js
**/
var easyuifix = {}; /**
* for easyloader.js
* add after row 13 usage: easyuifix.addLoadModules(_1);
*/
easyuifix.easyloader_addLoadModules = function (modules) {
$.extend(modules, {
juidatepick: {
js: rootPath+"/content/js/jquery-plugin/jquery-ui/js/jquery-ui-datepick.min.js",
css: rootPath+"/content/js/jquery-plugin/jquery-ui/css/jquery-ui.css"
},
daterange: {
js: rootPath+"/content/js/jquery-plugin/daterange/jquery.daterange.js",
css: rootPath+"/content/js/jquery-plugin/daterange/jquery.daterange.css",
dependencies: ["juidatepick"]
},
lookup: {
js: rootPath+"/content/js/jquery-plugin/lookup/jquery.lookup.js",
dependencies: ["combo"]
},
autocomplete: {
js: rootPath+"/content/js/jquery-plugin/autocomplete/jquery.autocomplete.js",
dependencies: ["combo"]
}
});
}; /**
* for easyloader.js
* add after row 181 usage: easyuifix.easyloader_setting(easyloader, src);
*/
easyuifix.easyloader_setting = function (easyloader,src) {
easyloader.theme = "default";
easyloader.locale = "zh_CN";
}; /**
* for jquery.parser.js
* add after row 89 usage: easyuifix.parser_addplugins($.parser.plugins);
*/
easyuifix.parser_addplugins = function (plugins) {
var arr = ["daterange", "lookup", "autocomplete"];
for (var i in arr)
plugins.push(arr[i]);
}; /**
* for jquery.tabs.js
* add after row 415 usage: easyuifix.tabs_showtabonselect(_5d);
*/
easyuifix.tabs_showtabonselect =function(tab){
tab.show(); //打开时其它页签先隐藏,,提升用户体验,点击时再显示
} /**
* for easyui-lang-zh_CN.js
* add last row: easyuifix.lang_zh_CN();
*/
easyuifix.lang_zh_CN = function () {
if ($.fn.lookup) {
$.fn.lookup.defaults.missingMessage = '该输入项为必输项';
}
}; /**
* for jquery.datagrid.js
* add after row 1137 usage: easyuifix.datagrid_beforeDestroyEditor(_10a, _10b, row);
* for jquery.easyui.min.js
* add after row 7622 usage: easyuifix.datagrid_beforeDestroyEditor(_530, _531, row);
*/
easyuifix.datagrid_beforeDestroyEditor = function (jq, rowIndex, row) {
var opts = $.data(jq, "datagrid").options;
if (opts.OnBeforeDestroyEditor) {
var editors = {}, list = $(jq).datagrid('getEditors', rowIndex) || [];
$.each(list, function () { editors[this.field] = this; });
opts.OnBeforeDestroyEditor(editors, row, rowIndex, jq);
}
}; /**
* for jquery.datagrid.js
* add after row 1101 usage: easyuifix.datagrid_afterCreateEditor(_104, _105, row);
* for jquery.easyui.min.js
* add after row 7586 usage: easyuifix.datagrid_afterCreateEditor(_52a, _52b, row);
*/
easyuifix.datagrid_afterCreateEditor = function (jq, rowIndex, row) {
var opts = $.data(jq, "datagrid").options;
if (opts.OnAfterCreateEditor) {
var editors = {}, list = $(jq).datagrid('getEditors', rowIndex) || [];
$.each(list, function () { editors[this.field] = this; });
opts.OnAfterCreateEditor(editors, row, rowIndex, jq);
}
}; /**
* for jquery.combo.js to convert disable to readonly
* add after row 210 usage: easyuifix.combo_disableToReadonly(_32, _33);
*/
easyuifix.combo_disableToReadonly = function (jq, b) {
var options = $.data(jq, "combo").options;
var combo = $.data(jq, "combo").combo;
if (b) {
options.disabled = true;
$(jq).attr("readonly", true);
combo.find(".combo-value").attr("readonly", true).addClass("readonly");
combo.find(".combo-text").attr("readonly", true).addClass("readonly");
} else {
options.disabled = false;
$(jq).removeAttr("readonly");
combo.find(".combo-value").removeAttr("readonly").removeClass("readonly");
combo.find(".combo-text").removeAttr("readonly").removeClass("readonly");
}
}; /**
* for jquery.combobox.js to showblank
* add after row 138 usage: easyuifix.combobox_showblank(_30, _2e);
*/
easyuifix.combobox_showblank = function (combobox, b) {
if (combobox.showblank) {
b.unshift(combobox.blankdefault);
}
} /**
* for jquery.combobox.js to showblank
* add after row 350 usage: easyuifix.combobox_defaultblank();
*/
easyuifix.combobox_defaultblank = function () {
$.fn.combobox.defaults = $.extend($.fn.combobox.defaults, {
showblank: false,
blankdefault: { value: '', text: '== 请选择 ==' }
});
} /**
* for datagrid.js
* add after row 2065 usage: if (easyuifix) easyuifix.datagrid_editor_extend();
* use such as: using("lookup", easyuifix.datagrid_editor_extend);
*/
easyuifix.datagrid_editor_extend = function () {
if ($.fn.datagrid) {
if ($.fn.numberspinner) {
$.extend($.fn.datagrid.defaults.editors, {
numberspinner: {
init: function (container, options) {
var input = $('<input type="text">').appendTo(container);
return input.numberspinner(options);
},
destroy: function (target) {
$(target).numberspinner('destroy');
},
getValue: function (target) {
return $(target).numberspinner('getValue');
},
setValue: function (target, value) {
$(target).numberspinner('setValue', value);
},
resize: function (target, width) {
$(target).numberspinner('resize', width);
}
}
});
} if ($.fn.autocomplete) {
$.extend($.fn.datagrid.defaults.editors, {
autocomplete: {
init: function (container, options) {
var input = $('<input type="text" class="z-text datagrid-editable-input">').appendTo(container);
return input.autocomplete(options);
},
destroy: function (target) {
$(target).autocomplete('destroy');
},
getValue: function (target) {
return $(target).val();
},
setValue: function (target, value) {
$(target).val(value);
},
resize: function (target, width) {
$(target).width(width);
}
}
});
} if ($.fn.lookup) {
$.extend($.fn.datagrid.defaults.editors, {
lookup: {
init: function (container, options) {
var input = $('<input type="text" class="z-text datagrid-editable-input">').appendTo(container);
return input.lookup(options);
},
destroy: function (target) {
$(target).lookup('destroy');
},
getValue: function (target) {
return $(target).lookup('getValue');
},
setValue: function (target, value) {
$(target).lookup('setValue', value);
},
resize: function (target, width) {
$(target).lookup('resize', width);
}
}
});
} $.extend($.fn.datagrid.defaults.editors, {
label: {
init: function (container, options) {
var input = $('<div></div>').appendTo(container);
return input;
},
destroy: function (target) { },
getValue: function (target) {
return $(target).html();
},
setValue: function (target, value) {
$(target).html(value);
},
resize: function (target, width) { }
}
});
}
}

    easyUI方法修改,改善方法,提升用户体验;注释中提示方法作用的位置

  

  2. knockout.bindings.js

/// <reference path="knockout-3.4.1.js" />
/**
* 程序名: knockout自定义绑定
**/ (function ($, ko) {
var jqElement = function (element) {
var jq = $(element);
if ($(document).find(element).length == 0) { //处理元素在父页面执行的情况
if ($(parent.document).find(element).length > 0)
jq = parent.$(element);
}
return jq;
}; /**
* value binding
* 例如:comboboxValue、lookupValue、combotreeValue
*/
ko.creatEasyuiValueBindings = function (o) {
o = $.extend({ type: '', event: '', getter: 'getValue', setter: 'setValue', fix: $.noop,formatter: function (v) { return v; }}, o); var customBinding = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var jq = jqElement(element), handler = jq[o.type]('options')[o.event], opt = {}; //handle the field changing
opt[o.event] = function () {
handler.apply(element, arguments);
var value = jq[o.type](o.getter);
if (valueAccessor() == null) throw "viewModel中没有页面绑定的字段";
valueAccessor()(value);
}; //handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
jq[o.type]("destroy");
}); o.fix(element, valueAccessor);
jq[o.type](opt);
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
value = ko.utils.unwrapObservable(valueAccessor());
jqElement(element)[o.type](o.setter, o.formatter(value));
}
};
ko.bindingHandlers[o.type + 'Value'] = customBinding;
}; ko.creatEasyuiValueBindings({ type: 'combobox', event: 'onSelect' });
ko.creatEasyuiValueBindings({ type: 'combotree', event: 'onChange' });
ko.creatEasyuiValueBindings({ type: 'datebox' , event: 'onSelect' , formatter: com.formatDate });
ko.creatEasyuiValueBindings({ type: 'lookup' , event: 'onChange' });
ko.creatEasyuiValueBindings({ type: 'numberbox' , event: 'onChange' }); /*
* enable、disable binding
* 例如:linkbuttonEnable、linkbuttonDisable
*/
ko.creatEasyuiEnableBindings = function (o) {
o = $.extend({ type: '',method:'Enable', options:function(v){return 'disabled';}, value: function (v) { return !v; } }, o);
var customBinding = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var enable = ko.toJS(valueAccessor());
$(element)[o.type](o.options(enable), o.value(enable));
}
};
ko.bindingHandlers[o.type + o.method] = customBinding;
};
ko.creatEasyuiEnableBindings({ type: 'linkbutton', options: function (b) { return {disabled:!b}; } });
ko.creatEasyuiEnableBindings({ type: 'linkbutton',method:'Disable', options: function (b) { return { disabled: b }; } }); _readOnlyHandles = {};
_readOnlyHandles.defaults = function (obj, b) {
b ? obj.addClass("readonly").attr("readonly", true) : obj.removeClass("readonly").removeAttr("readonly");
};
_readOnlyHandles.combo = function (obj, b) {
obj.combo(b ? "disable" : "enable");
}; /**
* readonly binding
* 例如:numberboxReadOnly、comboboxReadOnly,或者直接readOnly
*/
ko.creatEasyuiReadOnlyBindings = function (o) {
o = $.extend({ type: '', handler: _readOnlyHandles.defaults }, o);
var customBinding = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
o.handler($(element),ko.toJS(valueAccessor()));
}
};
ko.bindingHandlers[o.type ? (o.type + 'ReadOnly'): 'readOnly'] = customBinding;
}; ko.creatEasyuiReadOnlyBindings(); //default readonly
ko.creatEasyuiReadOnlyBindings({ type: 'numberbox' });
ko.creatEasyuiReadOnlyBindings({ type: 'combobox', handler: _readOnlyHandles.combo });
ko.creatEasyuiReadOnlyBindings({ type: 'datebox', handler: _readOnlyHandles.combo });
ko.creatEasyuiReadOnlyBindings({ type: 'combotree', handler: _readOnlyHandles.combo });
ko.creatEasyuiReadOnlyBindings({ type: 'lookup', handler: _readOnlyHandles.combo }); /**
* datasource bingding
*/
ko.bindingHandlers.datasource = {
init: function (element, valueAccessor) {
var jq = jqElement(element);
var ds = ko.toJS(valueAccessor());
if ($.isFunction(ds)) ds = ds.call();
if (jq.data('treegrid'))
jq.treegrid('loadData', ds);
else if (jq.data('datagrid'))
jq.datagrid('loadData', ds);
else if (jq.data('combotree'))
jq.combotree('loadData', ds);
else if (jq.data('combobox')) {
var val = jq.combobox('getValue'), ds = ds.rows || ds;
jq.combobox('clear').combobox('loadData',ds).combobox('setValue', val);
}
else if (jq.data('tree'))
jq.tree('loadData', ds.rows || ds);
}
}; /**
* grid binding
* datagrid、treegrid
*/
ko.creatEasyuiGridBindings = function (gridType) {
var gridBinding = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var grid = jqElement(element), opts = ko.toJS(valueAccessor()), url = opts.url;
var customLoader = function (queryParams) {
if (opts.pagination) {
var paging = grid.datagrid('getPager').pagination('options');
queryParams = $.extend(queryParams, { page: paging.pageNumber, rows: paging.pageSize });
}
com.ajax({
type: 'get',
url: url,
data: queryParams,
success: function (d) {
if ($.isFunction(opts.afterCustomSuccess)) opts.afterCustomSuccess(d);
grid[gridType]('loadData', d);
}
});
}; if (opts.treeField && opts.parentField) { //only for treegrid
opts.loadFilter = function (data) {
return utils.toTreeData(data.rows || data, opts.idField||opts.treeField, opts.parentField, "children");
};
} var handler = function () {
if (grid.data(gridType)) {
if (opts.customLoad)
customLoader(opts.queryParams);
else
grid[gridType](opts);
} else {
var defaults = {
iconCls: 'icon icon-list',
nowrap: true, //折行
rownumbers: true, //行号
striped: true, //隔行变色
singleSelect: true, //单选
remoteSort: true, //后台排序
pagination: false, //翻页
pageSize: 20,
contentType: "application/json",
method: "POST"
};
var winsize = function (size) {
var ret = {};
if (size && size.w) ret.width = jqElement(window).width() - size.w;
if (size && size.h) ret.height = jqElement(window).height() - size.h;
return ret;
}; opts = $.extend(defaults, opts, winsize(opts.size));
if (opts.customLoad) {
if (opts.remoteSort)
opts.onSortColumn = function (sort, order) { customLoader($.extend(opts.queryParams, { sort: sort, order: order })); }; grid[gridType](opts);
customLoader(opts.queryParams); if (opts.pagination)
grid[gridType]('getPager').pagination({ onSelectPage: customLoader });
}
else
grid[gridType](opts); valueAccessor()[gridType] = function () { return grid[gridType].apply(grid, arguments); }
valueAccessor()['$element'] = function () { return grid; };
if (opts.size) jqElement(window).resize(function () { grid[gridType]('resize', winsize(opts.size)); });
}
}; grid[gridType] ? handler() : using([gridType], function () {
handler();
if (gridType=='treegrid') com.loadCss('content/images/icon/icon.css', document, true);//解决图标被tree.css覆盖的问题
});
}
}; return gridBinding;
}; ko.bindingHandlers.datagrid = ko.creatEasyuiGridBindings('datagrid');
ko.bindingHandlers.treegrid = ko.creatEasyuiGridBindings('treegrid'); /**
* easyui binding
* 例如:easyuiCombotree、easyuiCombobox、easyuiLinkbutton
*/
ko.createEasyuiInitBindings = function (o) {
o = $.extend({ type: '' },o);
var customBinding = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var jq = jqElement(element), opt = ko.mapping.toJS(valueAccessor());
var handler = function () {
jq[o.type](opt);
};
jq[o.type] ? handler() : using(o.type, handler); //handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
jq[o.type]("destroy");
});
valueAccessor()["$element"] = function () { return jq };
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var jq = jqElement(element), opt = ko.mapping.toJS(valueAccessor());
if (jq[o.type]) jq[o.type](opt);
}
};
var bindName = 'easyui' + o.type.replace(/(^|\s+)\w/g, function (s) {return s.toUpperCase();});
ko.bindingHandlers[bindName] = customBinding;
}; ko.createEasyuiInitBindings({ type: 'tabs' });
ko.createEasyuiInitBindings({ type: 'tree' });
ko.createEasyuiInitBindings({ type: 'combotree' });
ko.createEasyuiInitBindings({ type: 'combobox' });
ko.createEasyuiInitBindings({ type: 'linkbutton' }); /**
* inputwidth、autoheight、autowidth binding
*/
ko.bindingHandlers.inputwidth = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var that = $(element), widthStr = ko.toJS(valueAccessor());
var calcWidth = function (w) {
var rate = 1
if (typeof w == 'string') {
if (w.indexOf("px") > -1 || w.indexOf("PX") > -1) w = w.replace("px", "").replace("PX", "");
if (w.indexOf("%") > -1) w = w.replace("%", "") / 100;
}
if (w > 0 && w <= 1) {
rate = w;
w = $(".val").width();
}
return w * rate;
}; var resizeWidth = function () {
var width = calcWidth(widthStr);
$.each([
{ selector: 'input.txtBox', handler: function (jq) { jq.width(width - 8); } }, //pading3*2 + border1*2 = 8
{ selector: 'input[comboname],input.combo-f', handler: function (jq) { jq.combo('resize', width); } }
], function () {
var jq = that.find(this.selector);
if (jq.length > 0) this.handler(jq);
if (that.is(this.selector)) this.handler(that);
});
}; resizeWidth();
$(window).resize(resizeWidth);
}
}; ko.bindingHandlers.autoheight = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var that = $(element), obserable = valueAccessor(),
height = $.isFunction(obserable) ? obserable() : obserable;
that.height($(window).height() - height);
$(window).resize(function () { that.height($(window).height() - height); });
}
};
ko.bindingHandlers.autowidth = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var that = $(element), obserable = valueAccessor(),
width = $.isFunction(obserable) ? obserable() : obserable;
that.width($(window).width() - width);
$(window).resize(function () { that.width($(window).width() - width); });
}
}; /**
* 实现js与页面绑定
*/
ko.bindingViewModel = function (viewModelInstance,node) {
using('parser', function () {
$.parser.onComplete = function () {
ko.applyBindings(viewModelInstance, node || document.body);
};
});
}; })(jQuery, ko);

    自定义绑定,使 knockout 和 easyUI 关联,作用于页面中

  

  3. receive.jsp

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>材料收料单</title>
<%@ include file="/common/head.jsp"%>
</head>
<body>
<div class="toolbar">
<a href="#" plain="true" class="easyui-linkbutton" icon="icon-arrow_refresh" title="刷新" data-bind="click:refreshClick">刷新</a>
<a href="#" plain="true" class="easyui-linkbutton" icon="icon-add" title="新增" data-bind="click:addClick" >新增</a>
<a href="#" plain="true" class="easyui-linkbutton" icon="icon-edit" title="编辑" data-bind="click:editClick" >编辑</a>
<a href="#" plain="true" class="easyui-linkbutton" icon="icon-cross" title="删除" data-bind="click:deleteClick" >删除</a>
<a href="#" plain="true" class="easyui-linkbutton" icon="icon-user-accept" title="审核" data-bind="click:auditClick" >审核</a>
<a href="#" plain="true" class="easyui-linkbutton" icon="icon-printer" title="打印" data-bind="click:printClick" >打印</a>
</div> <div class="container_12" style="position:relative;">
<div class="grid_1 lbl">收料单号</div>
<div class="grid_2 val"><input type="text" data-bind="value:form.billNo" class="easyui-autocomplete txtBox" data-options="url:rootPath+'/mms/receive!getBillNo.do'"/></div> <div class="grid_1 lbl">供应商</div>
<div class="grid_2 val"><input type="text" data-bind="value:form.supplierName" class="easyui-autocomplete txtBox" data-options="url:rootPath+'/mms/merchants!getNames.do'"/></div>
<div class="grid_1 lbl">合同名称</div>
<div class="grid_2 val"><input type="text" data-bind="value:form.contractCode" class="txtBox"/></div> <div class="clear"></div> <div class="grid_1 lbl">库房</div>
<div class="grid_2 val"><input type="text" data-bind="comboboxValue:form.warehouseCode,datasource:dataSource.warehouseItems" class="easyui-combobox txtBox " data-options="showblank:true"/></div>
<div class="grid_1 lbl">供应类型</div>
<div class="grid_2 val"><input type="text" data-bind="comboboxValue:form.supplyType,datasource:dataSource.supplyType" class="easyui-combobox txtBox " data-options="showblank:true" /></div>
<div class="grid_1 lbl">收料日期</div>
<div class="grid_2 val"><input type="text" data-bind="value:form.receiveDate,readOnly:true" class="txtBox easyui-daterange"/></div> <div class="clear"></div> <div class="prefix_9" style="position:absolute;top:5px;height:0;">
<a id="search" href="#" class="buttonHuge button-blue" data-bind="click:searchClick" style="margin:0 15px;">查询</a>
<a id="reset" href="#" class="buttonHuge button-blue" data-bind="click:clearClick">清空</a>
</div>
</div> <table data-bind="datagrid:grid">
<thead>
<tr>
<th field="billNo" sortable="true" align="left" width="90" >收料单号 </th>
<th field="supplierName" sortable="true" align="left" width="200" >供应商 </th>
<th field="supplyType" sortable="true" align="center" width="70" formatter="com.formateSupplyType" >供应类型 </th>
<th field="contractCode" sortable="true" align="left" width="100" >合同名称 </th>
<th field="warehouseName" sortable="true" align="left" width="100" >库房 </th>
<th field="receiveDate" sortable="true" align="center" width="120" formatter="com.formatTime" >收料日期 </th>
<th field="totalMoney" sortable="true" align="right" width="70" formatter="com.formatMoney" >金额 </th>
<th field="originalNum" sortable="true" align="left" width="90" >原始票号 </th>
<th field="doPerson" sortable="true" align="left" width="60" >经办人 </th>
<th field="remark" sortable="true" align="left" width="150" >备注 </th>
</tr>
</thead>
</table> <%@ include file="/common/foot.jsp"%>
<script type="text/javascript" src="viewModel/mms/mms.com.js"></script>
<script type="text/javascript" src="viewModel/mms/receive.js"></script>
<script type="text/javascript" src="report/common/report.js"></script> <script type="text/javascript">
using(['messager', 'dialog'], function(){
var data = ${data};
ko.bindingViewModel(new viewModel(data));
});
</script>
</body>
</html>

    材料收料单列表界面,应用 data-bind 与数据模型进行绑定

  4. receive.js

function viewModel(data){
com.formateSupplyType = utils.fnValueToText(data.dataSource.supplyType); var self = this;
this.dataSource = data.dataSource;
this.form = ko.mapping.fromJS(data.form);
delete this.form.__ko_mapping__;
this.grid = {
size: { w: 4, h: 94 },
url: rootPath + '/mms/receive!list.do',
queryParams: ko.observable(),
pagination: true,
customLoad: false
}; this.grid.queryParams(data.form); this.refreshClick = function () {
window.location.reload();
}; this.addClick = function () {
com.openTab("收料单明细", rootPath + '/mms/receive!add.do');
}; this.deleteClick = function () {
var row = self.grid.datagrid('getSelected');
if (!row) return com.message('warning', '请先选择一条收料单!');
com.message('confirm', '确定要删除选中的收料单吗?', function (b) {
if (b) {
com.ajax({
type: 'DELETE',
url: rootPath + "/mms/receive!delete.do?billNo=" + row['billNo'],
success: function () {
com.message('success', '删除成功!');
self.searchClick();
}
});
}
});
}; this.editClick = function () {
var row = self.grid.datagrid('getSelected');
if (!row) return com.message('warning', '请先选择一条收料单!');
com.openTab("收料单明细", rootPath + '/mms/receive!edit.do?billNo=' + row['billNo']);
}; this.searchClick = function () {
var param = ko.toJS(this.form);
this.grid.queryParams(param);
}; this.clearClick = function () {
$.each(self.form, function () { this(''); });
this.searchClick();
}; this.grid.onDblClickRow = this.editClick; this.auditClick = function () {
var row = self.grid.datagrid('getSelected');
if (!row) return com.message('warning', '请先选择一条收料单!');
mms.com.auditDialogList(function (d) {
com.ajax({
type: 'POST',
url: rootPath + "/mms/receive!audit.do?billNo=" + row['billNo'],
data: JSON.stringify(d),
success: function () {
com.message('success', '单据已审核!');
}
});
});
}; this.printClick = function () {
var arg = JSON.stringify(self.grid.$element().datagrid('options').queryParams);
var param = {jasper:"mms/receive",ds:"mmsReceiveDataSource",fileName:"材料收料单"+
"("+(utils.isEmpty(arg.receiveDate)?"":arg.receiveDate)+")",args:arg};
window.location.href = rootPath + "/mms/receive!report.do?param=" + JSON.stringify(param).replace(/"/g, "'");
};
}

    材料收料单列表界面的数据模型,利用 knockout 与界面绑定

四. 效果图

  1. 材料收料单列表界面: http://localhost:8080/ims/mms/receive.do

EasyUI+Knockout实现经典表单的查看、编辑

  2. 材料收料单编辑/新增界面: http://localhost:8080/ims/mms/receive!add.do

EasyUI+Knockout实现经典表单的查看、编辑

上一篇:javascript异步编程的前世今生,从onclick到await/async


下一篇:Java命令使用 jmap,jps,jstack,jstat,jhat,jinfo