TreeのDataDescriptorについて

これまであまりDataDescriptorについてあまり使おうと思ったことがなかったのですが、実はTreeにDataDescriptorを指定するとチョー便利だということがわかってきました。

たとえば、モデルオブジェクト自身はchildrenプロパティを持っていないことってよくあると思います。
モデル自体は単純であればあるだけよいわけですし、こっちのツリーとあっちのツリーでは子ノードにしたいデータプロパティが違っている、なんてときに、モデル側の実装をツリーごとに増やしたりしたくはないですよね。

そんなときには、DefaultDataDescriptorを継承したクラスを作成して、TreeのdataDescriptorプロパティに設定してやると、ツリーごとに「モデルノードから子を取得するための方法」とか「ノードが足されたときのモデル側の処理」などを外部から記述してやることが出来ます。dataProviderに指定したモデルが何一つ階層を持っていなくても表示できる、ということです。
Treeでやってはいけないのは、ツリーノード専用のオブジェクトを作って本来のノードオブジェクトをラップしてしまうこと。
作ったときはなんとなくエレガントに思えますが、他のコンポーネントへのドラッグ&ドロップのときに、ドラッグソースあるいはドロップされる側のどちらかが、本来のノードモデルにキャストしてやらなければならなくなるのです。

[追記]
横着してDefaultDataDescriptorを継承すると、作成できるはずの子ノードが作成できないなどの不具合が起こるようです。

さらにちゃんと検証してみると、Treeの場合、getChildrenで返すnodeオブジェクトは最終的にdataProviderの階層内にインスタンスとして含まれていなければならないようです。一時的にオブジェクトを作成して、それを子として作成することは出来ますが、そこからさらに子のノードを作ることが出来ません。
さらに詳しく言うと、この一時的なnodeを引数としてdescriptorのgetChildren()が呼び出されることがないので、展開しても子が作成されません。

したがって、DataDescriptorだけでツリー構造を完全に動的に構築させることは(ツリー末端を除いて)出来ないようです。

まとめてみると、役に立つのは、
・children以外のプロパティ名で子のインスタンスを持っているモデルの場合
・Drag&Dropでツリー内を移動させたいが、各階層のモデルへの追加や削除の方法がバラバラのとき
・(リーフとして)本来モデルの持っていない情報をツリー内に追加したいとき

しかし、子が展開できないのはショックでした。キャッシュの関係で各ノードオブジェクトのUIDをみているらしいのですが、これはやはり「モデルとしてツリー構造を事前に構築するべき」という意味なのかも。こうなってしまうと、他コンポーネントにドラッグアウトするときにモデルを変換するほうが安全かつ簡単といわざるを得ませんよね。