2011-01-31 2 views
2

Я обнаружил, что я не могу удалить узлы, которые еще не были отображены. Следующий код показывает, что я имею в виду. Я запустил его из командной строки Chrome (и Firebug) в то время как на http://dev.sencha.com/deploy/dev/exa...dow/hello.html (поскольку эта страница была предварительно загружена)Как удалить узел из Ext TreePanel, если узел не был обработан

Я набрал каждое заявление отдельно, чтобы убедиться, что проблем с асинхронными операциями не было (хотя данные дерева находятся в память)

Ext.getBody.update(''); 
// Tree with preloaded nodes in memory 
var tree = new Ext.tree.TreePanel({ 
    renderTo: Ext.getBody(), 
    width: 300, 
    height: 500, 
    rootVisible: false, 
    loader: new Ext.tree.TreeLoader({preloadChildren:true}), 
    root: new Ext.tree.AsyncTreeNode({ 
    expandend: true, 
    children: [ 
     {text: 'Folder 1', id: 'folder1', leaf: false, children: [ 
      {text: 'File 1', id: 'file1', leaf: true}, 
      {text: 'File 2', id: 'file2', leaf: true} 
     ]} 
    ] 
    }) 
}); 

// Try to delete 'File 1', notice that the folder has never been expanded 
tree.getRootNode().childNodes[0].childNodes[0].remove(true); 

// Expand the node and see that 'File 1' is still there 
tree.getRootNode().childNodes[0].expand(); 

// Delete the first child 1 again, it works now that it's been rendered 
tree.getRootNode().childNodes[0].childNodes[0].remove(true); 

Любые предложения о том, что делать?

ОТВЕТ

var nodeToRemove = tree.getRootNode().childNodes[0].childNodes[0]; 
if (!nodeToRemove.rendered) { 
    var children = node.parentNode.attributes.children; 
    Ext.each(children, function(child, index){ 
     if (child.id == nodeToRemove.id) { 
      chilren.splice(index, 1); 
      return false; 
     } 
    }) ; 
} else { 
    nodeToRemove.remove(true); 
} 
+0

Зачем включать узлы, если вы хотите их удалить? – Chandu

+0

@Cybermate: Это явно не используемый код, это просто сокращение.Дерево - это один вид данных, другие места в коде могут удалять «файлы» до того, как их «папка» будет расширена в дереве. –

ответ

1

Я, наконец, понял, на самом деле Co ndor от поддержки Ext-JS выяснил это для меня.

Проблема заключалась в том, что по умолчанию, TreeLoader очищает своих детей, когда TreeLoader # перезарядка называется (это называется по AsyncTreeNode # развернуть(), если опция clearOnLoad истинно (по умолчанию).

(TreeLoader) load : function(node, callback, scope){ 
     if(this.clearOnLoad){ 
      while(node.firstChild){ 
       node.removeChild(node.firstChild); 
      } 
     } 
     if(this.doPreload(node)){ // preloaded json children 
      this.runCallback(callback, scope || node, [node]); 
     } 

Так создания моего дерева загрузчиков с clearOnLoad: false исправляет мою проблему за исключением того, когда я удалить все дочерние узлы чтобы исправить, что мне нужен следующий патч:..

Ext.tree.TreeLoader.prototype.doPreload = 
Ext.tree.TreeLoader.prototype.doPreload.createSequence(
    function(node){ 
    if (node.attributes.children) { 
     node.attributes.children = [];  
    } 
    } 
); 

Вот ссылка на доб-Js нить:

http://www.sencha.com/forum/showthread.php?122681-Deleting-unrendered-nodes-from-a-tree-doesn-t-work&p=567459#post567459

@Pumbaa: Это решение, а не временное решение, как вы предложили, но я очень благодарен за вашу помощь.

-1

Пока TreeNode не расширяется, элементы не инициализированы в качестве компонентов ExtJS. До этого времени они просто сидят в массиве дочерних элементов (xtyped стандартных объектов javascript), смотрят на TreeNode.childNodes в документах API. Попробуйте удалить их из этого массива и затем расширить элемент. Это должно сделать трюк

Приветствия, Роб

+0

Простите, это совсем не правильно. – user123444555621

+0

Hi Rob: при использовании treeloader с preloadChildren, установленным в true, все узлы в массиве children создаются при рендеринге дерева (хотя соответствующий TreeNodeUI не отображается до его расширения). Что вы имеете в виду, удалив их из этого массива? Это то, что делает мой код. Вероятно, вы хотели удалить из массива attributes.children, но это не работает: attributes.children не имеет значения после того, как объекты TreeNode были созданы из конфигурации и помещены в массив childNodes. –

+0

Извините, я ошибся. Рад, что кто-то еще может помочь –

3

Ext.tree.TreePanel является один компонент, я ненавижу больше всего (с последующим FormPanel).

Вот что происходит: TreeLoader предварительно загружает дочерние узлы корневого узла из исходного объекта конфигурации, а также вызывает вызов AsyncTreeNode.expand, который будет в основном сбрасывать дерево.

Итак, вы собираетесь должны удалить узел из конфигурации вашего RootNode как это до расширения:

tree.getRootNode().attributes.children[0].children.shift(); 

Edit: На самом деле, это более интуитивным:

tree.getRootNode().childNodes[0].attributes.children.shift(); 

(делает то же самое, начиная с root.childNodes[0].attributes === root.attributes.children[0])

+0

Я сейчас пытаюсь это сделать ... вы говорите, что мой код должен работать, но загрузчик дерева недостаточно умен, чтобы обнаружить, что он предварительно загружает дочерние элементы для узла, и он воссоздает их из атрибутов. массив? –

+0

Он работает, спасибо! Я буду искать фактическую ошибку в их коде. –

+0

Справа. На самом деле, это не задача загрузчика, чтобы помнить, какие узлы были предварительно загружены. Флаги корневого узла сами загружаются. Тем не менее, «Папка 1» не помечена как загруженная, поэтому, как только вы вызываете 'expand()', загрузчик снова включается. – user123444555621