Domanda

I am creating an item selector with two boxes that move things back and forth within an extjs application. On the right box, I am creating buttons that serve to move items up and down. Essentially I am swapping the item with one above or below it. So, my code is straight forward in that regard

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;

    }

  }
}

All of this code seems to work fine, because after clicking my button, and checking the DOM in firebug, I can see that the selected nodes have moved in the array correctly, however, this effect is never shown within my treepanel. ???How do I make the treepanel update when it's elements change. ???

TreePanel heirarchy looks like this just to clarify

Root Node 'Chosen Folder Node' Array of items I am moving up and down within the 'folder'

I am USING VERSION 4.0.7

Attempting to use replaceChild() to fire an event to rerender does not behave as I expected

Changing:

var temp = theChosen.childNodes[i];
theChosen.childNodes[i] = theChosen.childNodes[i-1];
theChosen.childNodes[i-1] = temp;

To:

var temp = theChosen.childNodes[i];
theChosen.replaceChild(theChosen.childNodes[i-1], theChosen.childNodes[i]);
theChosen.replaceChild(temp, theChosen.childNodes[i-1]);

Results in odd behavior in which some nodes go missing. Certaintly not what I was looking for. Where am I going wrong here?

Tried the following code using the datachanged and (undocumented)refresh event:

Ext.getStore('storeId').fireEvent('datachanged', Ext.getStore('chosen') );
Ext.getStore('storeId').fireEvent('datachanged', Ext.getStore('chosen') );

This does not reload anything...

SOLUTION:

Use the insertChild method of nodeInterface....

I have noticed something strange in how insertChild works in that I need to change my index more based on moving up or down will explain with code below.

To move Up:

theChosen.insertChild( (i-1), theChosen.childNodes[i]);

To move down:

theChosen.insertChild( (i+2), theChosen.childNodes[i]);

Although the -1 vs +2 they both effectively move the item by one in the appropriate direction.

È stato utile?

Soluzione

If you want to update the view of the nodes, I recommend using yourTree.getView().refresh();

But you can avoid that by using parentNode.insertChild(index, childNode); where index is where you want the node to show up and parentNode is the parent to the nodes you are reordering. ChildNode can be a config for a new node or any other nodeinterface that already exists. If the node does already exist and you use the insertChild method to insert it, it will automatically remove that node from whereever else it is.

So as you provided in your question in response to my answer, your code will work with something like (this is probably how I'd do it, but this is untested):

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);
        }
    }
}

Altri suggerimenti

Edit:

Back to the the responsible event question... You need to fire the

'datachanged' 
'refresh'

Events on the store with the store as only param. That should cause a UI update. But please note that I just had a glimpse into the sourcecode and I am sure this can all be done much smarter. At least a DD solution for this exists already. If I find some time I my look into this again, but I guess you should be fine with these events for the first.

You never see anything cause you just do it without the appropriate methods that then fire the responsible events that cause rerender. Take a look at

There may also be more methods that can help on the Ext.data.NodeInterface. I recommend you to use these instead of doing it under hood without any responsible event fired.

In addition to my second comment (just a wild guess without knowing if that is exactly what you want):

MoveUp: function(button, event, eOpts){
    var target = Ext.getStore('storeId').getRootNode().findChild('text', 'Chosen folder');
    var selected = chosenPanel.getSelectionModel().getSelection();
    target.appendChild(selected);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top