Dojo はまりどころいろいろ

微妙にはまったところ、あれ?と思ったところを記す。

dijit

dijit は Dojo を使い始めた頃から、ちょこちょこはまっている。
まず、初めにきちんと意識しておくべきことは「dijit は単一のエレメントじゃない」こと。
(たぶんほとんどの)Widget は複数のHTMLエレメントが組み合わさって機能を実現している。例えば、Combobox なら、表示用の input 要素+値を保持する非表示の input 要素+下向き矢印用の div 要素+その他…というようにだ。
よって、通常のDOM操作の要領で dojo.byId() とやると動かない。dijit.byId() を使う必要がある。


さらに、子要素を追加するとき、通常のDOMノードなら、dojo.create(タグ名, 属性, 親ノード) とやるが、Widget の場合は、親Widget.attr("content", 子ノード) とやる。setContent() ではなく、attr()。setContent() の方がしっくりくる感じだが、deprecated になっている。おそらくは下位互換性を確保するためだと思うけど…

cookie

dojo.cookie() で cookie に保存することが出来るのだが、cookie に保存できるのは皆さんご存じの通り、文字列のみ。
せっかく、Dojo を使ってるんだから、

var hoge = new Object();
dojo.cookie("hoge", hoge);

とか出来るものと勝手に期待したりしたけど、そういう仕様にはなってない。ちゃんと、

var hoge = new Object();
dojo.cookie("hoge", dojo.toJson(hoge));

と、やってやらなければならない。まあ、toJson() があるだけでも、使う価値はあるということで。


そして、メソッドを持つようなオブジェクトは toJson() で変換できない。しかも、

var hoge = new Object();
var store = new dojo.data.ItemFileWriteStore({
                  data: hoge
              });

とやると、hoge がバインドされて、勝手にメソッドが追加される。hogecookie に保存したければ、

var hoge = new Object();
var store = new dojo.data.ItemFileWriteStore({
                  data: dojo.clone(hoge)
              });

等、一手間かけることが必要となる。今回はこの合わせ技でやられました><