35
+$#L őĄ Œö ƌƊƋƍĈƏĮƌƎĦİ BACKBONE.JSMVC始めませんか? 13725日木曜日

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

Embed Size (px)

DESCRIPTION

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

Citation preview

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

�+$#��L��őĄ��Œ� ö

ƌƊƋƍĈƏĮƌƎĦ�İ�

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

13年7月25日木曜日

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

ţćŘÇ

BE8BB4@ ���8B>"0<8����

ÁŲb½ĻŻtőĄ�~�~�hs�jT

ĭŹ{!0D0A2@8?B²�¼xwps_�hmT

ÆĈ{+��t_�Åxw�mYtjT

őĄzōtęŦzĉÀc^Ûij�|uĒY

m�xÞĐšðbzåčÊ�hs�jT

13年7月25日木曜日

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

fsfs

-41�®¸�!0D0*2@8?Bt

ÏpsY�uƉƉƉ

13年7月25日木曜日

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

n�n� ¾�^eo�eo�h�j�yƆ

ぱくたそ無料写真素材を使用しております。ありがとうございます!  http://www.pakutaso.com/about.html

13年7月25日木曜日

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

R ª¼«¾�¾ ƒ�

Q ¢¾�«¾� ƒ�

Q Ł�ŀ_«¾� ƒ�

R �°�´¹ ƒ�

¢¾�«¾� ƒ�

Ł�ŀ_«¾� ƒ�

íŭƐK� tjƆ

Ñ[|d�wzÏ�u_

���²¨µ¾ŧ{9A>=¥¾¡ëď

���ü_w«¾��żĚj�u ��íŭžƅ^Û��

��ż�nôóu

13年7月25日木曜日

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

$(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){

d�wĕitīYo�Z���

9A>=¥¾¡ëďėãÚńxk�k�Úń�īYo�Z

¥¾¡�3><�7B<;�zÂxÓĝho�Z

13年7月25日木曜日

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

$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 ) { }); });

d�wĕitīYo�Zu���

�¼®¹ http://jsdo.it/itoKami1123/3KAK

2;82:�¯¼¦xèïƂģtĠňÚń�īYo�Z

13年7月25日木曜日

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

o�puhmz{ŤYztjbv

n�n�uƀ`wps

13年7月25日木曜日

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

ţÜz�¾§t�

vdxÍ^īYsX�]

đ�sh�Y�j���

ぱくたそ無料写真素材を使用しております。ありがとうございます!  http://www.pakutaso.com/about.html

13年7月25日木曜日

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

lzu_SÛÊpmıƆ

!0D0*2@8?B�$,�tƆ·�­·¸{�02:1>=4�9A^�fcƆ

13年7月25日木曜日

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

$,�tŠ[�uPz�Zwæ_xw�zth�Z]T

�>=B@>;;4@

$>34;

,84E

��,84E^$>34;ÙĀ�ŧŐ

APIサーバ

��$>34;^�¾«��9A>=¥¾¡ëď

/\��ú�pm���

d���02:1>=4�9AtÏps��h�ZƆ

GET

13年7月25日木曜日

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

$,�tŠ[�uPz�Zwæ_xw�zth�Z]T

click!

�>=B@>;;4@

$>34;

,84E

���>=B@>;;4@^$>34;�úĪ

��,84E^$>34;ÙĀ�ŧŐ

APIサーバ

��$>34;^�¾«��9A>=¥¾¡ëď

��,84E^¶¾�ġÏ�ìbë� ��,84E^$>34;ÙĀ�ŧŐ

/\��ú�pm���

/Ŭ��m��

/\��ú�pm���

d���02:1>=4�9AtÏps��h�ZƆ

GET

13年7月25日木曜日

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

�D4=B

�02:1>=4�$>34;�02:1>=4��>;;42B8>=

�D4=B

�&$ũŖ�7B<;�

�02:1>=4�,84E

ŨŷƐ��02:1>=4�9A��D4=Bœń^ÒßƆ

�>=B@>;;4@$>34;

,84E

/4D4=B�58@4��/4D4=B�58@4��

�02:1>=4�,84E�4D4=BAt�&$ũŖŊŅ�¯¼¦�Ŏū

�D4=BřŇtğŜhsY�zt$>34;{,84EzÄh�wY�T

�02:1>=4�,84E�;8AB4=+>t$>34;úĪ�¯¼¦�Ŏū

13年7月25日木曜日

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

ow�x�¾«xŽŞhsY�9A>={d�wĕitjT

[ { "name": "ハンバーガ", "price": 300 }, { "name": "チーズバーガ", "price": 400 }, { "name": "照り焼きバーガ", "price": 500 }, { "name": "スペシャル", "price": 600 }]

http://jsrun.it/assets/g/q/B/s/gqBsC

13年7月25日木曜日

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

�k{½½½$,�z$z½½

$>34;]�ÏpsY_�jƆ

13年7月25日木曜日

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

$>34;t²¨µ¾¥¾¡�ŧŃ

var MenuItem = Backbone.Model.extend({

defaults:{

checked: false, // 選択フラグ

name: "", // ハンバーガー名

price: 0 // お値段

},

toggleChecked: function(){

this.set("checked", !this.get("checked") );

}

})

³¥¹ăēzÞįÕ

=4E��¼�¡¼�Ņė�ĩxÞįůþf��ÕT

�02:1>=4�..��ĜČ�4FB4=3�hm�z{Sţಠ£§�źät_�jT

dzÑt{SżĚ½ƄżĚłĖzÝĬ² £§��źähsY�jT

$>34;�64B�M:4GïN�tëďS�$>34;�A4B�M:4GïNNÕN�tůþh�jT

O�$>34;�A4Bĩx�M270=64N�¯¼¦^58@4f��jƆ

�02:1>=4�$>34;�ĜČhs

$4=C B4<�¼�¦·�¡Ƃģ�Ņė

13年7月25日木曜日

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

�>;;42B8>=t$>34;�IJy�jT

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;

!!!!}

});

ĴŔ$>34;zůþ

½ţಠ£§�żĚžƅƃŭ² £§�

�>;;42B8>=�E74@4xsţÜ^ĝpsY�³¥¹�ś�Ÿ�Ä^t_�jT

�02:1>=4��>;;42B8>=�ĜČO��>;;42B8>=uYZïàtjbv$,�z$tjT

�' �¾«z¬�

13年7月25日木曜日

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

ĸ{$,�zTTT

�>=B@>;;4@u,84E���X�p¿ŝxƑƑ

13年7月25日木曜日

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

Backbone.jsの ViewはControllerの機能も持ちます!

ご注意!

w�t,84Eu�>=B@>;;4@^Ü]�swY]ű]Ģ[sƆ

13年7月25日木曜日

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

�D4=B

�02:1>=4�$>34;�02:1>=4��>;;42B8>=

�D4=B

�&$ũŖ�7B<;�

�02:1>=4�,84E

ŨŷƐ��02:1>=4�,84E���,84E����>=B@>;;4@

�>=B@>;;4@$>34;

,84E

/4D4=B�58@4��/4D4=B�58@4��

l�l�$,�tĿ]pm�j�z]wW���

13年7月25日木曜日

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

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;

�02:1>=4�,84Et²¨µ¾ŧ��ť��ŧŃ

,84EzÞįç�8=8B80;8H4�² £§=4E�$4=C B4<�I<>34;�FFJ�t�B78A�<>34;��ůþt_�jT;8AB4=+>xs�$>34;zúĪ�¯¼¦Ŏū�þşhsY�jT

�02:1>=4�,84EzÃw®»¬¤����02:1>=4�,84E{�œńj��&$ũŖu$>34;��>;;42B8>=�Óĝj�du^Ûij�jT��B06%0<4�ĞþhmùíSĤŪ�&$ũŖ�Ņėhœńāųuh�jT��<>34;��=C;;�{īYs�ī]w`s�æÏ{ú��wYztjbvSÔÅŌŶñtīYs�jT

13年7月25日木曜日

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

!!!!!!!!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"

!!!!},

,84Et²¨µ¾ŧ��ť��ŧŃ

,84Exŕrbm$>34;{

Yqt�B78A�<>34;tÐ[�jT

B78A��4;xœńhsY�

9(C4@GũŖ^Ö��jT

���ţಠ£§

ddt{ÞįĠň�þşhs�jT

����¯¼¦zŋſ

��B78A��4;tŊŅhm�¯¼¦x

��,84E² £§�ŕrb�jT

13年7月25日木曜日

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

!!!!},

!!!!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);

!!!!}

});

,84Et²¨µ¾ŧ��ť��ŧŃ

½ţಠ£§�²¨µ¾ěÁÚń�

$>34;z² £§�ò}ÛhsY�jT

O�ŏğĠňhwYduƆ

ţಠ£§�³¥¹úĪ�êĨj�² £§�this.listenTo( menuItem, 'change', this.updateRender);

13年7月25日木曜日

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

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); }});

,84Et²¨µ¾ŧ�ŧŃ���,84E^œńj�ũŖ��º�¡tĞþt_�jT

���¥¾¡ëďĩxŊĽj�@4A4B�¯¼¦t;8AB)4=34@�ŵæh�jT

���$>34;zģܲ £§�ò}�jT

���ċģx$>34;^Ö��jT

����ťÜz,84E�Ņėhs¤¾­¹,84ExĴŔh�jT

13年7月25日木曜日

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

,84Et²¨µ¾ŧ�ŧŃƇŨŷƈ

ņĔhsY��+$#{d�wĕitjT

<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日木曜日

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

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; }});

,84EtżĚļ�²¨µ¾ƇƋťƈ�ŧŃ

²¨µ¾ŧuîi©¸tjTħŗéËz,84E�Ï��

Æö{�Ġň² £§x@4BC@=�B78A��qbs�jTĸz,84EtÐY�jT

13年7月25日木曜日

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

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);

}

});

,84EtżĚļ�²¨µ¾�ŧŃ

Ġň² £§z@4BC@=�B78A��Ðps�jT

C=34@A2>@4�9AzķŢt��¼¤��¦�÷þhs�jT

ÓĝhsY�$>34;t270=64^ŊŅj�u�>;;42B8>=x�270=64�¯¼¦^ŊŅh�jT

13年7月25日木曜日

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

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 );

}

});

,84Etíŭ�ŧŃ

B4<?;0B4Ƃģ�Ņė

B4<?;0B4Ƃģ�ÿťƆ

$4=C#8AB�Ŏū

13年7月25日木曜日

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

<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>

,84Etíŭ�ŧŃ�B4<?;0B4zÐYĥ

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日木曜日

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

,84Etíŭ�ŧŃ�B4<?;0B4zÐYĥ���

_.templateSettings = {

evaluate: /\{%(.+?)%\}/g,

interpolate: /\{\{(.+?)\}\}/g,

escape: /\{%-(.+?)%\}/g

};

ちなみに<%= value %>が使えない環境の場合は。。

ÀŮzÑnuÉÁz�ZwīĊxÝ�Ĭ���Ɔ

I��!0D0*2@8?B��J

II�lz��Ûâ�JJ

I�����¾®hsÛâ��J

13年7月25日木曜日

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

,84Et�®¸×Ì�ŧŃ

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日木曜日

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

�u���

UŤYĘV

��¯¼¦řŇ�ßņhsʼnŚíxī_�jY

�ÑƐ$>34;{,84Ezýø�h�wYƈ

�Ďáuī`ùĘ^ĺ�psY�ztÈÅz ¾��

_pu��jY{kT

UĹxwpmľV

�,84E�w��`Ăf`Đ^bwYuSjaxĆû

çhsh�ZT

�o�puhm®»�·±zùíSÞįząģ^Îŭ

x]]�]�T

13年7月25日木曜日

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

ÂŪĶÉÀz!0D0*2@8?BƁŊx{���"�&%��!*z�Zw

·�­·¸�Ðpsĵh`ƁŊhmY�ztjyT

13年7月25日木曜日

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

Ŵõ{egY�j]ƑƑ

13年7月25日木曜日

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

�¼®¹{do�xØƁhs\��j

http://jsdo.it/itoKami1123/A0MI

\h�Y

X�^uZegY�hmƆ

13年7月25日木曜日