Backboneのみでは結局オレオレプログラムとなってしまうので以下3つのプラグインを利用したサンプルです。
- Marionette.js
- Backbone.jsのViewやRouterの拡張、Layoutといったパーツごとの概念が入ったプラグイン
- backbone.stickit.js
- モデルとパーツのバインディングを簡潔にやってくれる
- Backbone-relational.js
- 複数のモデルやコレクションに参照関係を持たせてくれる
サンプルは1件の取引先に対して複数の担当者レコードが存在し、1つのページで編集ができるといった感じになっています
※サンプルはこちら ソースはgithubにも上げています。
サンプル 取引先情報
担当者情報
"use strict"; //テスト用のデータ var sample_data = { account:{id:"account1",name:"取引先1",tel:"xxx-xxx-xxxx"}, contact:[ {id:"contact1",name:"担当者1",tel:"xxx-xxx-xxx1",account_id:"account1"}, {id:"contact2",name:"担当者2",tel:"xxx-xxx-xxx2",account_id:"account1"}, {id:"contact3",name:"担当者3",tel:"xxx-xxx-xxx3",account_id:"account1"}, {id:"contact4",name:"担当者4",tel:"xxx-xxx-xxx4",account_id:"account1"}, {id:"contact5",name:"担当者5",tel:"xxx-xxx-xxx5",account_id:"account1"} ] }; //アプリケーション情報 var SampleApp = new Backbone.Marionette.Application(); //リージョンセット SampleApp.addRegions({ account:"#account_wrap", contact:"#contact_wrap", action:"#action_wrap" }); //取引先モデル/ビュー var Account_Model = Backbone.RelationalModel.extend({ relations: [{ type: Backbone.HasMany, key: 'id', relatedModel: 'Contact_Model', collectionType: 'Contact_Collection', reverseRelation: { key: 'account_id' } }] }); var Account_View = Backbone.Marionette.ItemView.extend({ model:Account_Model, bindings: { "input#name": "name", "input#tel": "tel", }, tagName:"dl", className:"account ", template:"#tmpl_account", onRender:function(){ this.stickit(); }, }); //担当者モデル/コレクション/ビュー var Contact_Model = Backbone.RelationalModel.extend({}); var Contact_Collection = Backbone.Collection.extend({ model: Contact_Model }); var ContactRow_View = Backbone.Marionette.ItemView.extend({ bindings: { "input.name": "name", "input.tel": "tel", }, tagName:"tr", template:"#tmpl_contactrow", onRender:function(){ this.stickit(); } }); var Contact_View = Backbone.Marionette.CompositeView.extend({ itemView:ContactRow_View, itemViewContainer:"tbody", template:"#tmpl_contact" }); //更新するボタンビュー(親モデルとなる取引先を受け取る) var Action_View = Backbone.Marionette.ItemView.extend({ template:"#tmpl_action", events:{ "click #save ":"save" }, save:function(){ console.log(this.model.toJSON()); } }); //初期描画処理 SampleApp.addInitializer(function(data){ //取引先 var account_model = new Account_Model(data.account); this.account.show(new Account_View({model:account_model})); //担当者 var contact_collection = new Contact_Collection(data.contact); this.contact.show(new Contact_View({collection:contact_collection})); //更新するボタン this.action.show(new Action_View({model:account_model})); }); //処理開始 SampleApp.start(sample_data);何か無駄にjqueryとか読み込んでますが依存関係はなく利用はしてないです。保存処理は手抜きしてしまいましたが、更新するボタンをクリックすると画面の入力値が既存のデータ(モデル・コレクション)が上書きされ、コンソールに出力されます。
JavaScript側はプログラムというよりJSON設定のみで処理が動くといった感覚でコーディングができます。
stickitやrelationalはチラホラ不具合の話も聞くので、導入には検討が必要ですがMarionetteは非常に重宝しています。
最近はAngular界隈が非常に賑やかになってきましたが、まだまだBackboneにはお世話になりそうです。
来年はd3.jsもガッツリやりたいなー