2013/12/27

[Marionette][relational][stickit]Backboneの各種プラグインを利用したサンプル

2013年ももうすぐ終わりなので最後にBackboneについて書いてみました。
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もガッツリやりたいなー