2011-12-28 5 views

ответ

3

Какую именно версию ExtJS4 вы используете?

В моей ситуации с ext-4.0.7-gpl я немного отлаживал обнаружение, что метод appendChild создает узел из и объекта, а затем выполняет некоторые операции обновления, касающиеся положения узла в дереве, например, установки следующего брата, родителя и т. д., см. [1].

При синхронизации в магазине используются методы getUpdatedRecords и getNewRecords [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 бета-не работает лучше для меня

Обновления с температурными решениями: Я взломал немного, и я думаю, решил проблему, переопределив метод appendChildNodeInterface, как показано ниже (только для установки свойства phantom, чтобы запись создавалась, а не обновлялась).

Обратите внимание: 1) Вы должны включать appendChild вызов в NodeInterfaceexpand метод обратного вызова, или ошибка с нажатием на пустой childNodes останется: новый узел появится где-то в неположенном месте; 2) Мне пришлось переопределить updateIndexesAbstractView, постарайтесь не делать этого, и, возможно, вы узнаете, почему; 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. Форма открывается, нажав иконку в actioncolumn нашего дерева сетки:

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 подмены:

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

Если бы тот же вопрос, обновление внутр-4.1.0-бета-2 починил это.

0

Причиной может быть неправильный формат данных, поступающих с сервера в ответ на ваш запрос. Синхронизация не происходит. Передайте «успешный» ключ со значением TRUE в ответе сервера.

0

Хмм ... попробуйте это ...

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

Смежные вопросы