2011-12-28 93 views

回答

3

你使用了什么样的ExtJS4?

在我的情况下,用ext-4.0.7-gpl调试了一下,发现appendChild方法创建了一个来自和object的节点,然后执行一些关于节点在树中的位置的更新操作,如设置next兄弟姐妹,父母等,见[1]。

同步时,商店使用getUpdatedRecordsgetNewRecords [2]方法来确定要运行哪个操作。更新或创建。不知何故,我们附加的孩子将被更新,而不是创建。

请注意,该方法不检查父节点的子节点是否已加载,只是将新节点推入空的childNodes数组;在所有这些操作结束之后,父节点的其他子节点不会显示在树中;如果更新操作所造成的新的id服务器端生成,代码突破上线original = me.tree.getNodeById(record.getId()); - 存在与客户端所产生的旧id没有这样的节点..

简单地说,我认为这是一个错误。

[1] http://docs.sencha.com/ext-js/4-0/source/NodeInterface.html#Ext-data-NodeInterface-method-appendChild [2] http://docs.sencha.com/ext-js/4-0/source/AbstractStore.html#Ext-data-AbstractStore-method-getUpdatedRecords

添加:ExtJS的4.1测试版2不为我

更新与临时解决方案工作得更好:我砍死了一下,认为我通过覆盖下面的NodeInterfaceappendChild方法解决了这个问题(只是为了设置phantom属性,以便创建记录,而不是更新)。

请注意: 1)你应该包括你的电话appendChildNodeInterfaceexpand方法回调,或推到空childNodes仍将错误:新节点将在错误的地方某处出现; 2)我不得不覆盖AbstractViewupdateIndexes,尽量不要这样做,也许你会发现原因; 3)当商店试图在下一次同步时删除我们新创建的节点时有一些问题 - 无法跟踪它; 0)我没有办法ExtJS的,甚至JS大师,所以随时纠正这个技巧)

Ext.data.NodeInterface.oldGpv = Ext.data.NodeInterface.getPrototypeBody; 
Ext.data.NodeInterface.getPrototypeBody = function(){ 
    var ret = Ext.data.NodeInterface.oldGpv.apply(this, arguments); 

    ret.appendChild = function(node, suppressEvents, suppressNodeUpdate) { 
     var me = this, 
     i, ln, 
     index, 
     oldParent, 
     ps; 


     if (Ext.isArray(node)) { 
      for (i = 0, ln = node.length; i < ln; i++) { 
       me.appendChild(node[i]); 
      } 
     } else { 
      node = me.createNode(node); 

      if (suppressEvents !== true && me.fireEvent("beforeappend", me, node) === false) { 
       return false; 
      } 

      index = me.childNodes.length; 
      oldParent = node.parentNode; 

      if (oldParent) { 
       if (suppressEvents !== true && node.fireEvent("beforemove", node, oldParent, me, index) === false) { 
        return false; 
       } 
       oldParent.removeChild(node, null, false, true); 
      }else{ 
       node.phantom = true; 
      } 

      if(me.isLoaded()){ 
       index = me.childNodes.length; 
       if (index === 0) { 
        me.setFirstChild(node); 
       } 

       me.childNodes.push(node); 
       node.parentNode = me; 
       node.nextSibling = null; 

       me.setLastChild(node); 

       ps = me.childNodes[index - 1]; 
       if (ps) { 
        node.previousSibling = ps; 
        ps.nextSibling = node; 
        ps.updateInfo(suppressNodeUpdate); 
       } else { 
        node.previousSibling = null; 
       } 
       node.updateInfo(suppressNodeUpdate); 
      } 

      //console.log('appendChild was called'); 

      // I don't know what this code mean even given the comment 
      // in ExtJS native source, commented out 

      // As soon as we append a child to this node, we are loaded 
      //if (!me.isLoaded()) { 
      // me.set('loaded', true); 
      //} 

      // If this node didnt have any childnodes before, update myself 
      //else 
      //if (me.childNodes.length === 1) { 
      // me.set('loaded', me.isLoaded()); 
      //} 

      if (suppressEvents !== true) { 
       me.fireEvent("append", me, node, index); 

       if (oldParent) { 
        node.fireEvent("move", node, oldParent, me, index); 
       } 
      } 

      return node; 
     } 
    }; 
    return ret; 
}; 

这是我的代码从一种形式domainForm采取值添加一个节点。

var node = grid.store.getAt(rowIndex); 
node.expand(false, function(){ 
    var newDomain = domainForm.getValues(); 
    newDomain.parent = {id: node.raw.id}; // i don't know whether you'll need this 
    var newNode = node.appendChild(newDomain); 
    me.store.sync(); 
}); 

updateIndexes超控器:形式通过点击我们的树网格的actioncolumn图标可打开

Ext.override(Ext.view.AbstractView, { 
    updateIndexes : function(startIndex, endIndex) { 
     var ns = this.all.elements, 
      records = this.store.getRange(), 
      i; 

     startIndex = startIndex || 0; 
     endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length < records.length?(ns.length - 1):records.length-1)); 
     for(i = startIndex; i <= endIndex; i++){ 
      ns[i].viewIndex = i; 
      ns[i].viewRecordId = records[i].internalId; 
      if (!ns[i].boundView) { 
       ns[i].boundView = this.id; 
      } 
     } 
    }  
}); 
1

有同样的问题,更新到EXT-4.1.0-β-2修复。

0

原因可能是来自服务器的数据格式错误,无法响应您的请求。 同步不会发生。在服务器响应中传递“成功”键值为TRUE。

0

嗯......试试这个...

beforeitemexpand(node, eOpts){ if (node.data.expanded) return false }