Ext JS 5 のViewModel を使ってみる

Ext JS 5 から導入された ViewModel を使ってみます。 ViewModel はデータをビューにバインドする新しい方法です。 いろいろと機能が高く、API ドキュメントやチュートリアルを読んでも、まだすべてが解説されているというわけではないようです。

今回は、2way binding と呼ばれる、View と ViewModel 間での双方向のデータバインディングについて実験してみます。 まずは、 Sencha Cmd 5.0 でプロジェクトを作ってみます。

[js] $ sencha -sdk /path/to/sdk generate workspace ext5_ws $ cd ext5_ws/ext $ sencha generate app MyApp ../firstapp [/js]

以前と同じようにスケルトンのプロジェクトが生成されます。 スケルトンの中にも、すでに ViewModel が使われているのがわかります。 view/main ディレクトリの中に、Main.js の他に、MainController.js と MainModel.js があります。

[js] Ext.define(‘MyApp.view.main.MainModel’, { extend: ‘Ext.app.ViewModel’, alias: ‘viewmodel.main’, data: { name: ‘MyApp’ } //TODO – add data, formulas and/or methods to support your view }); [/js]

ここでは、name に MyApp を設定しています。

[js] items: [{ xtype: ‘panel’, bind: { title: ‘{name}’ }, [/js]

View の方では、このようにパネルのタイトルにその値を、バインドしています。 これで、MainModel.js の方の、 data.name を変更してやると、表示も変わるのがわかります。

では、双方向のデータバインディングを実験してみます。

フォームを作ります。

スケルトンをまねて、view/form 下に Form.js / FormController.js / FormModel.js を作ります。

app/view/form/FormModel.js

[js] Ext.define(‘MyApp.view.form.FormModel’, { extend: ‘Ext.app.ViewModel’, alias: ‘viewmodel.form’, data: { name: ‘鬼瓦権三’, zip: ‘999-9999’, email: ‘gonzo@example.com’ } }); [/js]

これが ViewModel です。ここでは、data を定義しています。 alias コンフィグで、’viewmodel.hoge’ とすると、hoge がこの ViewModel の名前になります。

app/view/form/Form.js

[js] Ext.define(‘MyApp.view.form.Form’, { extend: ‘Ext.form.Panel’, xtype: ‘app-form’, requires: [ ‘MyApp.view.form.FormModel’, ‘MyApp.view.form.FormController’ ], bodyPadding: 10, viewModel: { type: ‘form’ }, controller: ‘form’, bind: { title: ‘{name}’ }, items: [{ fieldLabel: ‘氏名’, xtype: ‘textfield’, bind: ‘{name}’ },{ fieldLabel: ‘郵便番号’, xtype: ‘textfield’, bind: ‘{zip}’ },{ fieldLabel: ‘メール’, xtype: ‘textfield’, bind: ‘{email}’ }], tbar: [{ text: ‘保存’, handler: ‘onSave’, bind: { disabled: ‘{!name}’ } }] }); [/js]

普通のフォームです。 ViewModel と、これから作る ViewController をrequires に入れています。 Main.js の所では requires に入れてないのにロードされています。これ不思議なんですよね。

  1. viewModel コンフィグで、ViewModel を指定しています。ViewModel の alias で定義したものですね。
  2. 同様に、controller コンフィグで、ViewController を指定しています。
  3. items 配列の中の、各フィールドに bind コンフィグで、ViewModel のデータをバインドしています。 このように、ブレスを使って定義するのは XTemplate と似ています。
  4. tbar コンフィグでツールバーを定義していますが、そこでも bind コンフィグを使っています。 これは、名前が入力されていない場合に、ボタンを disabled にするという指定です。
  5. またボタンのハンドラーには、文字列が設定されています。ViewController のこのメソッドが呼ばれます。

app/view/form/FormController.js

[js] Ext.define(‘MyApp.view.form.FormController’, { extend: ‘Ext.app.ViewController’, alias: ‘controller.form’, onSave: function () { console.log(‘Save Button Clicked!’); } }); [/js]

こちらでは、onSave メソッドを定義しているだけです。 View の handler で文字列にて “onSave” を設定しましたから、このメソッドが呼び出されます。

app/view/main/Main.js
[js] requires: [ ‘MyApp.view.form.Form’ ], …. },{ region: ‘center’, xtype: ‘app-form’ }] [/js]

Center リージョンのコンポーネントのタブパネルを削除して、このフォームを表示させます。 requires もわすれずに。

これで、ブラウザをリロードして結果を見てみましょう。

viewmodel

このように表示されます。 ViewModel の data がフォームフィールドにセットされているのがわかります。 このフォームでは、タイトルにも {name} がバインドされているので、name を変更すると、タイトルバーが自動的に変更されるのがわかると思います。

フォーム上のデータを書き換えて、コンソールに次の様に入力してみてください。

[js] Ext.ComponentQuery.query(‘app-form’)[0].getViewModel().getData() [/js]

data の内容が即座に変わっているのがわかります。

bind の定義は、

[js] bind: { title: ‘{name}’ }, [/js]

のように、bind のオブジェクトの中に、コンフィグのキーとバインドするプレースホルダをセットするのが普通だと思うのですが、field の部分では、 bind: '{name}' といきなりプレースホルダをセットできています。 このあたり、ちょっとまだわからないところがありますが、なかなかに便利そうな機能なので、調査していきたいと思います。

あと ViewModel と Store の関係についての記事も書きたいな。

1 thought on “Ext JS 5 のViewModel を使ってみる

  1. ピンバック: Ext JS 5 資料リスト | Sunvisor Lab. Ext JS 別館

コメントは停止中です。