最近又开始写ExtJS了,用的是最新版本ExtJS4.0.7,这玩意现在也开始搞MVC分层了,了解了一下感觉还不错!以前使用2.X系列的时候虽然也自己定义并规范化了一些,但是整体代码感觉有些乱,界面和事件处理以及数据都在一起,而且扩展起来也不太方便,现在使用这种MVC的方式确实不错!
由于有半年多没接触过ExtJS了,现在不光分了MVC而且,API也有不小的变化,消失了一些类又多了一些类,不过还是挺好上手的,也许是因为以前用过吧。下面说说这几天在使用TreeStore遇到的一个问题。
情景是这样的:在已有的树上增加一个节点,然后执行TreeStore的sync()方法与服务器进行同步后报错“original is undefined”。
这个操作完成后,树上(界面)已经添加成功,查看数据库也一样是成功添加了,服务器返回的JSON也没有问题,可是它就是报错!检查发现,这个错出现在TreeStore源码的onUpdateRecords方法中的“parentNode = original.parentNode;”这一句上。源码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | onUpdateRecords: function(records, operation, success){ if (success) { var me = this, i = 0, length = records.length, data = me.data, original, parentNode, record; for (; i < length; ++i) { record = records[i]; original = me.tree.getNodeById(record.getId()); parentNode = original.parentNode; if (parentNode) { // prevent being added to the removed cache original.isReplace = true; parentNode.replaceChild(record, original); original.isReplace = false; } } }); } } |
服务器端返回的JSON格式是这样的:
1 | {success: true, data: [{id: 100, text: '新节点', leaf: true, parentId: 90}]} |
我觉得这个方法应该是在返回的JSON中success为true时,将data中的数据逐一替换掉UI上相应的节点(因为新节点先在UI上出现,然后才同步到服务器),而这时候“original = me.tree.getNodeById(record.getId())”却始终找不到相应的节点,为什么呢?我想是这样的:
添加节点的代码是:
var node = {text: '新节点', leaf: true}; parentNode.appendChild(node); store.sync();
当“parentNode.appendChild(node);”执行完毕,UI上便出现了新增加的node,而且store中也多出了一条记录,当sync()被执行并接收到服务器端返回到JSON,便开始执行onUpdateRecords方法了,而这时候,UI上那个node的id默认是“0”,而服务器端返回的数据中id是“100”,所以就找不到了!这样一想,官方的这个是不是有点太不符合逻辑了?返回的JSON中不是有parentId吗!直接用它找到父节点,再通过父节点找到其下最后一个子节点(这个就是新添加的节点)然后替换之。想明白了,开始动手override一下源码中到这个方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | Ext.override(Ext.data.TreeStore, { onUpdateRecords: function(records, operation, success){ if (success) { var me = this, i = 0, length = records.length, data = me.data, original, parentNode, record; for (; i < length; ++i) { record = records[i]; parentNode = me.tree.getNodeById(record.data.parentId); original = parentNode.lastChild; if (parentNode) { // prevent being added to the removed cache original.isReplace = true; parentNode.replaceChild(record, original); original.isReplace = false; } } if (record.dirty) { record.commit(); } } } }); |
再把程序跑起来看看,没问题了!网上竟然没找到相关信息,难道就我遇到了?