ツリー コントロールの状態を維持するにはどうすればよいですか? ツリーが崩壊するのではなく、データプロバイダーが更新されたときにツリーの状態を維持したいと思います。
8 に答える
このようなものはどうですか:
var openItems:Object = tree.openItems; tree.dataProvider = myNewDataProvider; tree.openItems = openItems; tree.validateNow();
新しいdataProviderが古いdataProviderと根本的に異なる場合、これがどの程度うまく機能するかはわかりませんが、ツリーノードを遅延ロードしている場合は機能します。
これが私がそれを機能させた方法です。キーは呼び出すことです
*yourTreeInstance*.validateDisplayList();
ツリーのデータプロバイダーを更新した後。以下の私のコード:
<fx:Script>
<![CDATA[
[Bindable]
var treeDataProvider:XML;
private function onTreeCreated(event:FlexEvent):void{
// update value with new XML here;
treeDataProvider = <node name="root">
<node name="child 1">
<node name = "grand child 1"/>
</node>
</node>;
myTree.openItems = treeDataProvider..node;
myTree.validateDisplayList();
}
]]>
</fx:Script>
<mx:Tree id="myTree" labelField="@name" dataProvider={treeDataProvider}
creationComplete="onTreeCreated(event)"/>
これにより、ツリー全体が開いたままになります。
これは実際にはかなり簡単に行うことができます。コンポーネントを参照するだけでなく、その dataProvider にコンポーネントがバインドされていることを確認する必要があります。つまり、mxml では、dataProvider を割り当てるための中括弧構文です。また、DPは[Bindable]である必要があります。
これを行うと、データ プロバイダーを更新 (ノードの追加、削除、名前の変更など) するたびに、コントロールで自動的に更新されます。手動による無効化や更新は不要です。
実際のコード例が必要な場合はお知らせください。
BlazeDS を使用するプロジェクトでは、ユーザー エクスペリエンスを損なうことなく、ツリー コンポーネント データの更新と再読み込みを行う必要がありました (データの再読み込み時にすべてのノードが閉じられました)。「以前に開かれたノードは?」というタブを保持するのではなく、そして「スクロール位置は?」Tree コンポーネント データの新しい状態を既存のデータ プロバイダーに挿入する方法を見つけました。
これを自動的に行う方法はないと思います(ただし、ツリーコントロールを使用する必要はありませんでした)。ツリーコントロールを拡張し、状態の記録を自分で処理するのが最善の策だと思います。
たとえば、コンポーネントに新しいデータオブジェクトを設定する前に状態チェック関数を実行できるように、データプロパティをオーバーライドする可能性があります。ヘルプを見ると方法があります
isItemOpen(item:Object):Boolean,
と
expandItem(item:Object, open:Boolean, animate:Boolean = false, dispatchEvent:Boolean = false, cause:Event = null):void
各ノードを再帰的に実行し、ノードが開いているかどうかを確認して、そのノードの状態を保存する必要があります。次に、新しいデータプロバイダーで再描画されたら、新しいノードを再帰的に実行し、以前に開いていたノードがあるかどうかを確認し、開いている場合は展開します。
ノードを表すデータオブジェクトにIUIDインターフェイスを実装する必要があります。UIDは、通常はオブジェクト内のデータから構築される一意の識別子ですが、これをオーバーライドして、データプロバイダーの更新間で永続的なGUIDにする方が正確な場合もあります。したがって、UIDが一致する場合、新しいデータプロバイダーを使用するときに上記が機能します。
それが理にかなっていることを願っています。
openItems を保存し、データプロバイダーが更新された後にそれらを再度設定することを含む Inferis の回答は、dataprovider 配列コレクション内のオブジェクトに IUID インターフェイスを実装することと組み合わせて機能しました。
IUID の詳細: http://livedocs.adobe.com/flex/3/html/help.html?content=about_dataproviders_8.html
次のスニペットを順番に
var openItems:Object = tree.openItems;
tree.dataProvider = myNewDataProvider;
tree.openItems = openItems;
tree.validateNow();
また
callLater(keepOpenStateItems);
private function keepOpenStateItems():void {
tree.openItems = openTreeItems;
}
動作するには、mattbilson と Michelle のアドバイスに従う必要があります。彼らは絶対に正しいです。
ツリー dataprovider に含まれるオブジェクトの IUID を実装しただけです。コレクションの更新により、ツリーは実際に以前の状態に保たれます。