目标
使用ajax获取到json数据后,通过ko绑定到表格,然后通过jquery.gridgroup插件实现行合并,效果如下:
步骤
1.引入插件
<script src="~/Scripts/jquery-1.8.2.min.js"></script> <script src="~/Scripts/knockout-3.4.0.debug.js"></script> <script src="~/Scripts/knockout.mapping-latest.js"></script> <script src="~/Scripts/jquery.gridgroup.js"></script>
2.配置KO
function JobTaskViewModel() { var self = this; self.JobTaskList = ko.observableArray([]); self.RemoveJobTask = function() { $('#job_task_table tbody tr').remove(); }; self.AfterAddJobTask = function (node, index, elem) { //一般情况下KO的foreach afterAdd事件,每添加一行执行三次 //node.nodeType 分别是3,1,3 等于1的时候说明已经添加到dom中 if (node.nodeType == 1 && index == self.JobTaskList().length - 1) { { console.debug(index); $('#job_task_table').gridgroup({ head: null, column: [0, 1],refresh:true }); } } }; } var jobTaskViewModel = new JobTaskViewModel(); ko.applyBindings(jobTaskViewModel);
Table配置:
1 <table width="826" id="job_task_table" class="zwgl_wrap_table zwgl_wrap_table_s"> 2 <thead> 3 <tr style="background-color: rgb(247, 247, 247);"> 4 <th width="100">名称一</th> 5 <th width="100">名称二</th> 6 <th width="60">用户</th> 7 <th width="60">目标</th> 8 <th width="60">交付</th> 9 <th width="60">任务</th> 10 </tr> 11 </thead> 12 <tbody data-bind="foreach:{data:JobTaskList, afterAdd:AfterAddJobTask}"> 13 <tr> 14 <td data-bind="text: ProjectName"></td> 15 <td data-bind="text: JobTitle"></td> 16 <td data-bind="text: TaskUserName"></td> 17 <td data-bind="text: TargetDeliveryNum"></td> 18 <td data-bind="text: RealDeliveryNum"></td> 19 <td data-bind="text: TaskNum"></td> 20 </tr> 21 </tbody> 22 </table>
ajax请求:
1 $.ajax({ 2 cache: false, 3 url: '@Url.Action("GetJobDeliveryNumAndTaskNum")', 4 type: 'post', 5 data: obj, 6 success: function (obj) { 7 if (obj.Success) { 8 if (obj.Result.length > 0) { 9 jobTaskViewModel.JobTaskList.removeAll(); 10 jobTaskViewModel.RemoveJobTask(); 11 jobTaskViewModel.JobTaskList(obj.Result); 12 13 } else { 14 15 } 16 17 } 18 else { 19 20 } 21 }, 22 error: function (a) { 23 24 } 25 });
总结
上面这些步骤其实是走了弯路,因为gridgroup的设计是第一次执行缓存表格数据,所以后续的查询总是合并行后展示的数据是以前的。
(function ($) {
$.fn.extend({
gridgroup: function (options) {
//获取表参数
var gridConfig = this.data["tableData"];
//初始化表参数
if (!gridConfig) {
修改后
(function ($) {
$.fn.extend({
gridgroup: function (options) {
//获取表参数
var gridConfig = this.data["tableData"];
//初始化表参数
if (!gridConfig || (options.refresh||false)) {
这样就就可以在ajax返回结果后,顺序执行KO绑定和gridgroup分组了。
success: function (ret) {
if (ret.Success) {
jobTaskViewModel.JobTaskList.removeAll();
$('#job_task_table tbody tr').remove();
jobTaskViewModel.JobTaskList(ret.Result);
$('#job_task_table').gridgroup({ head: null, column: [0, 1], refresh: true });
}
else {
console.debug("任务统计失败," + obj.Result);
}
},
Table代码也可以改成
<tbody data-bind="foreach:JobTaskList">
Model去掉多余的代码变成
function JobTaskViewModel() { var self = this; self.JobTaskList = ko.observableArray([]); }
这样写是不是感觉KO好清爽啊!!!!
有篇文章对于理解afterAdd执行三次做了说明:
afterAdd及beforeRemove函数会固定收到三个参数,element、index及data,其中 element 为模板容器中的各元素,
实际运作时afterAdd/beforeRemove会收到不同的element被呼叫三次,原因是除了<tr>之外,<tbody>到<tr>之间的空白、</tr>到</tbody>间的空白也各算一个Element,(FF和chrome是忽略这个空格的)其 nodeType 为3即TEXT_NODE, 代表TEXT_NODE。 因此三次传入的element分别为TEXT_NODE、ELEMENT_NODE、TEXT_NODE,而第二次传入的ELEMENT_NODE是<tr>...</tr>间的内容,才是我们需要处理的对象,故加入if (elems.nodeType == 1)的判断。
要注意,一旦调用了了beforeRemove,konckout.js就不再自动帮你移除该笔数据在网页对应的元素,必须自行处理,但这也提供开发人员绝对的控制权,可自由安排HTML元素要怎么从网页上退出。