1

extjsアプリケーション内で物事を前後に移動する2つのボックスを備えたアイテムセレクターを作成しています。右側のボックスでは、アイテムを上下に移動するためのボタンを作成しています。基本的に、私はアイテムをその上または下のアイテムと交換しています。だから、私のコードはその点で簡単です

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の階層は、明確にするために次のようになります。

ルートノード'選択されたフォルダノード'フォルダ内で上下に移動しているアイテムの配列'フォルダ'

バージョン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および(文書化されていない)refreshイベントを使用して次のコードを試しました。

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対+2ですが、どちらもアイテムを適切な方向に1つずつ効果的に移動します。

4

2 に答える 2

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);
        }
    }
}
于 2012-09-06T13:30:27.727 に答える
1

編集:

責任あるイベントの質問に戻る...あなたは

'datachanged' 
'refresh'

ストアをパラメータとしてのみ使用するストアのイベント。これにより、UIが更新されます。しかし、私はソースコードを垣間見たばかりであり、これはすべてはるかに賢くできると確信していることに注意してください。少なくともこれに対するDDソリューションはすでに存在します。時間があればもう一度調べますが、最初はこれらのイベントで大丈夫だと思います。

再レンダリングを引き起こす責任のあるイベントを発生させる適切なメソッドなしでそれを実行するだけで、何も発生しません。を見てみましょう

Ext.data.NodeInterfaceで役立つメソッドが他にもある可能性があります。責任あるイベントが発生することなく、内部で使用するのではなく、これらを使用することをお勧めします。

私の2番目のコメントに加えて(それがまさにあなたが望むものであるかどうかを知らずにただの野蛮な推測):

MoveUp: function(button, event, eOpts){
    var target = Ext.getStore('storeId').getRootNode().findChild('text', 'Chosen folder');
    var selected = chosenPanel.getSelectionModel().getSelection();
    target.appendChild(selected);
}
于 2012-09-06T12:10:14.733 に答える