Upload
toshio-ehara
View
2.379
Download
1
Embed Size (px)
DESCRIPTION
HTML5+α @福岡 - 第20回 2013/7/25(木) 「HTML5+α @福岡」と「ゴノツクヒ」のコラボイベントで発表させて頂きました! BACKBONE.JSでMVC始めませんか?
Citation preview
�+$#��L��őĄ��Œ� ö
ƌƊƋƍĈƏĮƌƎĦ�İ�
BACKBONE.JSでMVC始めませんか?
13年7月25日木曜日
ţćŘÇ
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日木曜日
fsfs
-41�®¸�!0D0*2@8?Bt
ÏpsY�uƉƉƉ
13年7月25日木曜日
n�n� ¾�^eo�eo�h�j�yƆ
ぱくたそ無料写真素材を使用しております。ありがとうございます! http://www.pakutaso.com/about.html
13年7月25日木曜日
R ª¼«¾�¾ ƒ�
Q ¢¾�«¾� ƒ�
Q Ł�ŀ_«¾� ƒ�
R �°�´¹ ƒ�
¢¾�«¾� ƒ�
Ł�ŀ_«¾� ƒ�
íŭƐK� tjƆ
Ñ[|d�wzÏ�u_
���²¨µ¾ŧ{9A>=¥¾¡ëď
���ü_w«¾��żĚj�u ��íŭžƅ^Û��
��ż�nôóu
13年7月25日木曜日
$(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日木曜日
$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日木曜日
o�puhmz{ŤYztjbv
n�n�uƀ`wps
13年7月25日木曜日
ţÜz�¾§t�
vdxÍ^īYsX�]
đ�sh�Y�j���
ぱくたそ無料写真素材を使用しております。ありがとうございます! http://www.pakutaso.com/about.html
13年7月25日木曜日
lzu_SÛÊpmıƆ
!0D0*2@8?B�$,�tƆ·�·¸{�02:1>=4�9A^�fcƆ
13年7月25日木曜日
$,�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日木曜日
$,�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日木曜日
�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日木曜日
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日木曜日
�k{½½½$,�z$z½½
$>34;]�ÏpsY_�jƆ
13年7月25日木曜日
$>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日木曜日
�>;;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日木曜日
ĸ{$,�zTTT
�>=B@>;;4@u,84E���X�p¿ŝxƑƑ
13年7月25日木曜日
Backbone.jsの ViewはControllerの機能も持ちます!
ご注意!
w�t,84Eu�>=B@>;;4@^Ü]�swY]ű]Ģ[sƆ
13年7月25日木曜日
�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日木曜日
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日木曜日
!!!!!!!!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日木曜日
!!!!},
!!!!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日木曜日
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日木曜日
,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日木曜日
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日木曜日
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日木曜日
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日木曜日
<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日木曜日
,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日木曜日
,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日木曜日
�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日木曜日
ÂŪĶÉÀz!0D0*2@8?BƁŊx{���"�&%��!*z�Zw
·�·¸�Ðpsĵh`ƁŊhmY�ztjyT
13年7月25日木曜日
Ŵõ{egY�j]ƑƑ
13年7月25日木曜日
�¼®¹{do�xØƁhs\��j
http://jsdo.it/itoKami1123/A0MI
\h�Y
X�^uZegY�hmƆ
13年7月25日木曜日