我正在创建一个带有两个框的项目选择器,它们可以在extjs应用程序中来回移动。在右侧框中,我创建了用于上下移动项目的按钮。基本上我是在上面或下面交换一个项目。所以,我的代码在这方面是直截了当的
MoveUp: function(button, event, eOpts){
var theChosen = Ext.getStore('storeId').getRootNode().findChild('text', 'Chosen folder');
var chosenPanel = Ext.ComponenetQuery.query('#chosenTreePanel')[0];
var selected = chosenPanel.getSelectionModel().getSelection();
for( var i = 1; i < theChosen.childNodes.length; i++){
if(Ext.Array.contains(selected, theChosen.childNodes[i]) && (!Ext.Array.contains(selected, theChosen.childNodes[i-1]){
var temp = theChosen.childNodes[i];
theChosen.childNodes[i] = theChosen.childNodes[i-1];
theChosen.childNodes[i-1] = temp;
}
}
}
所有这些代码似乎都运行正常,因为在单击我的按钮并检查firebug中的DOM后,我可以看到所选节点已正确移动到数组中,但是,此效果永远不会显示在我的treepanel中。 ???如何在树形图更改时更新树形图。 ???
TreePanel heirarchy看起来只是为了澄清
根节点 '选择文件夹节点' 我在“文件夹”中上下移动的项目数组
我正在使用版本4.0.7
尝试使用replaceChild()来触发重新呈现的事件并不像我预期的那样行为
更改:
var temp = theChosen.childNodes[i];
theChosen.childNodes[i] = theChosen.childNodes[i-1];
theChosen.childNodes[i-1] = temp;
要:
var temp = theChosen.childNodes[i];
theChosen.replaceChild(theChosen.childNodes[i-1], theChosen.childNodes[i]);
theChosen.replaceChild(temp, theChosen.childNodes[i-1]);
导致某些节点丢失的奇怪行为。当然不是我想要的。我在哪里错了?
使用datachanged和(未记录的)刷新事件尝试以下代码:
Ext.getStore('storeId').fireEvent('datachanged', Ext.getStore('chosen') );
Ext.getStore('storeId').fireEvent('datachanged', Ext.getStore('chosen') );
解决方案:
使用nodeInterface ....的insertChild方法。
我注意到insertChild的工作原理有些奇怪,我需要根据向上或向下移动来更改我的索引,这将通过以下代码解释。
向上移动:
theChosen.insertChild( (i-1), theChosen.childNodes[i]);
向下移动:
theChosen.insertChild( (i+2), theChosen.childNodes[i]);
虽然-1 vs +2他们都有效地将项目按适当的方向移动了一次。
答案 0 :(得分:5)
如果要更新节点视图,我建议使用yourTree.getView()。refresh();
但是你可以通过使用parentNode.insertChild(index,childNode)来避免这种情况;其中index是您希望节点显示的位置,parentNode是您要重新排序的节点的父节点。 ChildNode可以是新节点或已存在的任何其他节点接口的配置。如果节点已经存在并且您使用insertChild方法插入它,它将自动从该节点移除该节点。
因此,当您在回答我的答案时提供的问题时,您的代码将使用类似的东西(这可能是我做的,但这是未经测试的):
MoveUp: function(button, event, eOpts){
var chosenPanel = Ext.ComponenetQuery.query('#chosenTreePanel')[0];
var selectedNodes = chosenPanel.getSelectionModel().getSelection();
for( var i = 0; i < selectedNodes.length; i++){
var currentNode = selectedNodes[i];
if(!currentNode.isFirst())
{
var parentNode = currentNode.parentNode;
var newIndex = parentNode.indexOf(currentNode) - 1;
parentNode.insertChild(newIndex, currentNode);
}
}
}
答案 1 :(得分:1)
修改强> 的
回到负责任的活动问题...... 你需要解雇
'datachanged'
'refresh'
商店中的事件,商店仅作为参数。这应该会导致UI更新。但请注意,我只是对源代码有一瞥,我相信这一切都可以做得更聪明。至少已存在DD solution。 如果我找到一些时间,我会再次看到这个,但我猜你应该对第一次这些事件没问题。
你永远不会看到任何原因导致你只是在没有适当的方法的情况下执行它,然后触发导致重新渲染的责任事件。看看
可能还有更多方法可以帮助Ext.data.NodeInterface。我建议你使用这些而不是在引擎盖下进行,而不会触发任何负责任的事件。
除了我的第二条评论(只是一个疯狂的猜测而不知道这是否正是你想要的):
MoveUp: function(button, event, eOpts){
var target = Ext.getStore('storeId').getRootNode().findChild('text', 'Chosen folder');
var selected = chosenPanel.getSelectionModel().getSelection();
target.appendChild(selected);
}