问题描述:在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);以上内容转自:http://dinguangx.iteye.com/blog/1900652
需要更正一点,到目前为止官方发布的最新版本为2.0,GitHub上有个2.1的好像还不如2.0稳定,2.0版本的“setData”方法是不支持直接设置JSON格式数据的,所以解决这个问题的方法应该是添加一个文件或者添加一个后台方法,返回数据“
{"rows":[{}],"total":0}”