问题描述:在OMUI的一个可编辑的表格omGrid中,如果没有对组件设置dataSource,在执行insertRow操作时,表格中不会插入新记录,而通过自行扩展该组件为其配置dataSource之后(参见【Operamasks-UI】omGrid直接设置json数据给dataSource),执行deleteRow时会出现js报错的问题。
问题分析:
首先对于表格未设置dataSource时,直接执行insertRow操作,表格中未插入新记录的问题,是因为官方在开发该可编辑插件时,认为dataSource一定是会配置的,即使该返回一个空的数据集合也可以,如{rows:[],total:0}。通过om-grid和om-grid-roweditor的源代码的分析得知,roweditor插件是通过_onRefresh()函数对数据进行初始化的,代码的执行顺序图如下:
从图中可以看到,如果dataSource未设置或者加载数据失败的话,是不会调用_onRefreshCallbacks的,也就是说roweditor没有被初始化,所以在insertRow时不会成功。
再来研究一下这个执行顺序,会发现在_init()执行时,已经完成了对_onRefreshCallbacks的调用,而在init()执行之后,om-grid-roweditor插件才为om-grid注入了一个_onRefresh函数,从理论上来说,roweditor初始化是不会被完成的,但是为什么设置过dataSource的omGrid就没有问题了呢?了解了jquery的ajax调用机制之后,应该就会知道jquery加载数据是异步加载的,所以在omGrid加载数据时,roweditor已经初始化过了。而前面提到的自行扩展omGrid设置dataSource方式中,直接通过json数据作为数据源进行初始化时,代码执行是顺序执行的,同样会出现roweditor未被初始化的情况,导致在deleteRow时报js错误。如果尝试将om-grid中加载数据的ajax请求改为同步请求,也同样会出现deleteRow报js错误的情况。这算是om-grid-roweditor深藏的一个bug??
解决方案:
有了前面的分析,得出的解决方案是在组件初始化完成之后再为组件设置值,如下:
var data={"rows":[{}],"total":0}; $('#grid').omGrid({ title : '表格', limit:15, //dataSource:data, editMode:"all", colModel : [ {header : 'ID', name : 'id', width : 100, align : 'center'}, {header : '地区', name : 'city', width : 120, align : 'left',editor:{editable:true}}, {header : '地址', name : 'address', align : 'left', width : 'autoExpand' ,renderer:function(value,rowData,rowIndex){ return value + "<img src='tool_tip.gif'/>"; } } ] }); $("#grid").omGrid("setData",data);