2011-12-28 97 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 }