ふとつぶやいていた件について
「あー、そういわれれば確かに。なんでComboBoxでhidenNameを指定すると取得できるんだろか?」
ととっても新鮮な気付きをいただきました。
で、ちょっと調べてみた。
ちょっと読んだだけだからばっちりあってるとはかぎらないけど、
概要はあってるはず。
まず、しょっぱなから本題からそれるけど、storeプロパティに配列指定だけで動いている
仕組みを追ってみた。
storeを配列で指定した場合、ComboBoxのstoreは内部でストアマネージャでlookupしてる。
指定されたidが配列だったら'field1'、'field2'…というフィールド名でArrayStoreを内部で生成してるようです。
だから配列で設定しても内部ではArrayStoreなんですね。
次。
FormPanel.getForm().getValuesで取得な話。
form.getValuesは内部でExtのコンポーネントのgetValue()をしているわけじゃなく、
HTMLElementのvalueを取得している。
もう少し構造を追ってみる。
getValuesはBasicFormで実装されてて,
Ext.lib.Ajax.serializeForm(this.el.dom);となっている。
key=valueの形でelement.name = element.value/element.textになる。
各値は&結合。
このelementはExt.ElementじゃなくてDomのエレメント。
serializeFormするときのelement.valueはDomのHTMLInputElement.valueということになる。
で、DomのHTMLInputElement.valueはtypeが「text,file,password」の時は入力されている値がそのまま
セットされるためシリアライズするときのvalueは表示されているものが設定される。
ということになるっぽい。
ComboBoxっていったってもとはTextFiledクラスを継承したTrggerFieldクラスを継承してるだけで、
選択肢がみえているのはComboListLayerで別Divでそう見させているから。
実はinputタグのtypeがtext。
だからgetValuesすると表示している値が取得できてしまうのである。っぽい。
まずはこれがComboBoxがgetValuesで取得するとvalueが取得できない理由でした。
ではhiddenNameを設定するとなぜ取得できるのか。。
hiddenNameを設定するとComboBox内部でinputタグをtypeをhiddenで作成する。
DomのHTMLInputElement.valueはtypeが「button,hidden,submit,reset,image,checkbox,radio」の時は
value属性値が設定されるからhiddenタグはvalue値になるわけ。
ComboboxのSetValueでhiddeenField.valueにvalue値を設定しているもんね。
だからシリアライズするときはvalue値が設定される。
と、こういう解釈で良いのかな??。。
でもひとつ腑に落ちない。
hiddenNameを設定するとvalueが取得できて、いままで取得できてた元の値が取得できなくなるのはなぜか?
insertSiblingで挿入しているので
type='text'な値とtype='hidden'な値が取得できても良いじゃないか。
とおもった。
前に書いた様に、
getValuesで取得できるのはExt.lib.Ajax.serializeFormでシリアライズしてるから。
でその対象の条件は!element.disabled && name。
が、hiddenNameが設定してあると元となる表示されている方のエレメントはname属性がついていない。
なぜか。
このname属性、ComboBoxのhiddenName指定すると
onRender内で
submitValue = falseにする。
で、ComboBoxの基底クラスであるFieldクラスのonRenderでは
submitValue === falseだと
this.el.dom.removeAttribute('name');
としていてname属性を削除している。
ということでname属性が無くなり、
getvaluesしても取得できないんだ。。。
↑hiddenName未設定時のDomツリー
↑hiddenName設定時(「hidden」という名前で設定)のDomツリー
====
おさらい。
ComboBoxその1:storeを配列で指定した場合の話
ComboBoxのstoreは内部でストアマネージャでlookupしてる。指定されたidが配列だったら'field1'、'field2'…というフィールド名で
ことでArrayStoreを内部で生成してた。
だから配列で設定しても内部ではArrayStoreなんですね。
ComboBoxその2:Comboboxの値の話
フォーム内の値はHTMLElementのvalueをシリアライズ化しているのでCombboxの実体はtype=textなので表示されている
値がvalueとなっちゃうよ。ということ。
ComboBoxその3-1:Comboboxの値の話
表示している値(displayFiled)じゃなくて(valueFild)が取得したい場合はhiddenNameを指定する。
これを指定するとinsertSiblingでhiddenタグをname属性をhiddenNameで挿入してくれる。
で、元からあるinputタグのname属性は削除される。
ComboBoxその3-2:フォームのgetValuesについて
内部でformが抱えるDomエレメント分まわしてシリアライズ化する。key(name属性)/value(value属性)で。
で、そのときの対象は!element.disabled && name。
=====
まとめ
ComboBoxを利用するときは配列指定であれば特にArrayStore=SimpleStoreは
指定することなく利用できるようです。
hiddenNameを指定することで値が取得できるようになるのは
内部でinputタグをtype=hiddenで作成しているからgetForm時のシリアライズ化時に
value値をちゃんと取得してくれるから。
hiddenNameを指定するといままで設定していたname属性は排除されて
シリアライズ化対象から外れます。
=====
おしまい。
自分なりにすっきり!!
0 件のコメント:
コメントを投稿