Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

BACKBONE.JSでMVC始めませんか?

HTML5+α @福岡 - 第20回 2013/7/25(木)
「HTML5+α @福岡」と「ゴノツクヒ」のコラボイベントで発表させて頂きました!

BACKBONE.JSでMVC始めませんか?

  • Login to see the comments

BACKBONE.JSでMVC始めませんか?

  1. 1. BACKBONE.JSでMVC始めませんか? 13年7月25日木曜日
  2. 2. 13年7月25日木曜日
  3. 3. 13年7月25日木曜日
  4. 4. ぱくたそ無料写真素材を使用しております。ありがとうございます!  http://www.pakutaso.com/about.html 13年7月25日木曜日
  5. 5. 13年7月25日木曜日
  6. 6. $(function(){ // menu表のデータを取得 $.ajax({ url:'/assets/g/q/B/s/gqBsC', dataType: 'json', }).done(function( menuList ) { // メニュー表の作成 var $menuTable = $('#menu'); _.each( menuList, function( item, idx){ var $tr = $('<tr>'); $menuTable.append( $tr); var $chk = $('<input type="checkbox" />').data({ "idx":idx, "name":item.name, "price":item.price}); $tr.append( $('<td>').append( $chk)) .append( $('<td>').text( item.name)) .append( $('<td>').text( item.price)); }); // イベントの取り付け $menuTable.on('click','input[type=checkbox]',function(event){ 13年7月25日木曜日
  7. 7. $tr.append( $('<td>').append( $chk)) .append( $('<td>').text( item.name)) .append( $('<td>').text( item.price)); }); // イベントの取り付け $menuTable.on('click','input[type=checkbox]',function(event){ var $selectedMenuTable = $('#selected-menu'); $selectedMenuTable.empty(); var sum=0; var $inputs = $menuTable.find('input[type=checkbox]'); $inputs.each( function( ){ var $input = $(this); if ( $input.prop('checked') ){ var data = $input.data(); var $tr = $('<tr>'); $tr.append( $('<td>').text( data.name)) .append( $('<td>').text( data.price)); $selectedMenuTable.append($tr); sum += data.price; } }); $('#sum-price').text(sum); }); }).fail(function( data ) { }).always(function( data ) { }); }); http://jsdo.it/itoKami1123/3KAK 13年7月25日木曜日
  8. 8. 13年7月25日木曜日
  9. 9. ぱくたそ無料写真素材を使用しております。ありがとうございます!  http://www.pakutaso.com/about.html 13年7月25日木曜日
  10. 10. 13年7月25日木曜日
  11. 11. APIサーバ GET 13年7月25日木曜日
  12. 12. click! APIサーバ GET 13年7月25日木曜日
  13. 13. 13年7月25日木曜日
  14. 14. [ { "name": "ハンバーガ", "price": 300 }, { "name": "チーズバーガ", "price": 400 }, { "name": "照り焼きバーガ", "price": 500 }, { "name": "スペシャル", "price": 600 } ] http://jsrun.it/assets/g/q/B/s/gqBsC 13年7月25日木曜日
  15. 15. 13年7月25日木曜日
  16. 16. var MenuItem = Backbone.Model.extend({ defaults:{ checked: false, // 選択フラグ name: "", // ハンバーガー名 price: 0 // お値段 }, toggleChecked: function(){ this.set("checked", !this.get("checked") ); } }) 13年7月25日木曜日
  17. 17. var!MenuList!=!Backbone.Collection.extend({ !!!!model:!MenuItem, !!!!url:!'/assets/g/q/B/s/gqBsC', !!!!sumPrice:!function(){ !!!!!!!!var!checkedMenuItems!=!this.where({!checked:true!}); !!!!!!!!var!sum!=!0; !!!!!!!!_.each(checkedMenuItems,function(model){ !!!!!!!!!!!!sum!+=!model.get("price"); !!!!!!!!}); !!!!!!!!return!sum; !!!!} }); 13年7月25日木曜日
  18. 18. 13年7月25日木曜日
  19. 19. Backbone.jsのViewは Controllerの機能も持ちます! ご注意! 13年7月25日木曜日
  20. 20. 13年7月25日木曜日
  21. 21. var!MenuItemView!=!Backbone.View.extend({ !!!!tagName:!'tr', !!!!model:!null,!//":MenuItem !!!!initialize:!function(!options){ !!!!!!!!var!menuItem!=!this.model; !!!!!!!!this.listenTo(!menuItem,!'change',!this.updateRender); !!!!}, !!!!createRender:!function(){ !!!!!!!!var!menuItem!=!this.model; 13年7月25日木曜日
  22. 22. !!!!!!!!this.listenTo(!menuItem,!'change',!this.updateRender); !!!!}, !!!!createRender:!function(){ !!!!!!!!var!menuItem!=!this.model; !!!!!!!!var!$chk!=!$('<input!type="checkbox"!/>'); !!!!!!!!var!name!=!menuItem.get("name"); !!!!!!!!var!price!=!menuItem.get("price"); !!!!!!!!this.$el !!!!!!!!!!!.append($('<td>').append($chk)) !!!!!!!!!!!.append($('<td>').text(name)) !!!!!!!!!!!.append($('<td>').text(price)); !!!!}, !!!!events:!{ !!!!!!!!"click":"onClick_menuItem" !!!!}, 13年7月25日木曜日
  23. 23. !!!!}, !!!!events:!{ !!!!!!!!"click":"onClick_menuItem" !!!!}, !!!!onClick_menuItem:!function(event){ !!!!!!!!var!menuItem!=!this.model; !!!!!!!!menuItem.toggleChecked(); !!!!}, !!!!updateRender:function!(){ !!!!!!!!var!menuItem!=!this.model; !!!!!!!!var!$chk!=!this.$('input[type="checkbox"]'); !!!!!!!!var!checked!=!menuItem.get("checked"); !!!!!!!!$chk.prop('checked',checked); !!!!} }); this.listenTo( menuItem, 'change', this.updateRender); 13年7月25日木曜日
  24. 24. var MenuListView = Backbone.View.extend({ el:'#menu', collection: null, //:MenuList initialize: function(options){ this.listenTo(this.collection,'reset',this.listRender); }, listRender: function(){ this.collection.each(this.createMenuItem,this); }, createMenuItem: function(menuItem){ var opt = {model:menuItem}; var menuItemView = new MenuItemView(opt); menuItemView.createRender(); this.$el.append( menuItemView.$el); } }); 13年7月25日木曜日
  25. 25. <div id="application" > <table id="menu" ></table> <table id="selected-menu"></table> <div id="sum-price-pane" > <script id="sum-price-pane-template" type="text/template" > 合計:<span ><%= sumPrice %></span> </script> </div> </div> 13年7月25日木曜日
  26. 26. var SelectedItemView = Backbone.View.extend({ tagName: 'tr', model: null, // :MenuItem initialize: function(options){ var selectedItem = this.model; }, createRender: function(){ var menuItem = this.model; var name = menuItem.get("name"); var price = menuItem.get("price"); this.$el .append($('<td>').text(name)) .append($('<td>').text(price)); return this; } }); 13年7月25日木曜日
  27. 27. var SelectedListView = Backbone.View.extend({ el: '#selected-menu', collection: null, // :MenuList initialize: function(options){ this.listenTo(this.collection,'change',this.updateRender); }, createItem: function(checkedItem){ var selItemView = new SelectedItemView({model:checkedItem}); this.$el.append( selItemView.createRender().$el); }, updateRender: function(){ this.$el.empty(); var checkedItems = this.collection.where({ checked:true }); _.each(checkedItems,this.createItem,this); } }); 13年7月25日木曜日
  28. 28. var SumPriceView = Backbone.View.extend({ el: '#sum-price-pane', collection: null, // :MenuList template: null, // :_.template(x) initialize: function(options){ this.template = _.template( $('#' + this.el.id + '-template').html() ); this.listenTo(this.collection,'reset',this.render); this.listenTo(this.collection,'change',this.render); }, render: function(){ var menuList = this.collection; var sumPrice = menuList.sumPrice(); var html = this.template( { sumPrice: sumPrice } ); this.$el.empty() .html( html ); } }); 13年7月25日木曜日
  29. 29. <div id="application" > <table id="menu" ></table> <table id="selected-menu"></table> <div id="sum-price-pane" > <script id="sum-price-pane-template" type="text/template" > 合計:<span ><%= sumPrice %></span> </script> </div> </div> var SumPriceView = Backbone.View.extend({ el: '#sum-price-pane',   ・・・省略・・・ initialize: function(options){ this.template = _.template( $('#' + this.el.id + '-template').html() );   ・・・省略・・・ }, render: function(){ var menuList = this.collection; var price = menuList.sumPrice(); var html = this.template( { sumPrice: price } ); this.$el.empty() .html( html ); } }); $(‘#id’)でテンプレート書式を取得してま す。以下3種類があります。 <%= そのまま %> <%- エスケープ %> <% JavaScript実行 %> 同名プロパティの設定値が テンプレートの中で使用されます。 13年7月25日木曜日
  30. 30. _.templateSettings = { evaluate: /{%(.+?)%}/g, interpolate: /{{(.+?)}}/g, escape: /{%-(.+?)%}/g }; ちなみに<%= value %>が使えない環境の場合は。。 13年7月25日木曜日
  31. 31. var ApplicationView = Backbone.View.extend({ el: '#application', collection: null, // :MenuList initialize: function(options){ this.collection = new MenuList(); var op = { collection:this.collection}; var menuListView = new MenuListView(op); var selectedListView = new SelectedListView(op); var sumPriceView = new SumPriceView(op); }, start: function(){ this.collection.fetch({reset: true}); } }); $(function(){ (new ApplicationView()).start(); }); 一つのCollection(Model) を複数のViewが利用する事で 複数のView間の整合性が保た れます。 アプリケーション開始時に APIサーバにGETしてJSON取得し ます。 [注]{reset:true}が無いと resetイベントが発火しません。 13年7月25日木曜日
  32. 32. 13年7月25日木曜日
  33. 33. 13年7月25日木曜日
  34. 34. 13年7月25日木曜日
  35. 35. http://jsdo.it/itoKami1123/A0MI 13年7月25日木曜日

×