javascriptもbackbone.jsならスッキリ ~mvcぽいのを初体験!~
DESCRIPTION
第4回福岡市西区プログラム勉強会で発表させて頂いた資料です。 HTML5+α @福岡 - 第20回 2013/7/25(木) で発表した「BACKBONE.JSでMVC始めませんか?」を元に作成しています。TRANSCRIPT
ť�ÿţďēżñ´Á�½·îęÐ
ƦƤƥƧĔƨļƦƩĵ�ĵ�
JavaScriptもBACKBONE.JSならスッキリ~MVCぽいのを初体験!~
ぱくたそ無料写真素材を使用しております。ありがとうございます! http://www.pakutaso.com/about.html
13年7月28日日曜日
ŵĒŪÍ
AD7AA3?����7A= /;7����
ÇƈdÃʼnƔwţď�����jv�lU
ĻƏ~�/C/@1?7>A¸�Â{zsv`�jpU
ÌĔ~)��w`�Ë{z�pZwlU
ţď}ŜwĨŸ}ĕÆe_äŀ��xĠZ
p�{çĝųüd}îęÐ�jv�lU
13年7月28日日曜日
Ìĵ}ŚŹ~
�)"!��K��ţď�ť� ÿwŚŹjpâċ�
ÛņjpŐwlU
��� �$#���(w"+�ć��n�^ƫ��)"!��K��ţď�ť� ÿ
6AA>���DDD�@:723@6/?3�<3A�7A=9/;7�����0/190=<3��������
13年7月28日日曜日
hvhv
,30�´¾��/C/(1?7>Aw
ÔsvZ�xƣƣƣ
13年7月28日日曜日
q�q��/C/(1?7>A_
ƌđąðjv
Ɔ�ƅ�zZ�į_
Ƅŕjvj�j�lU
ぱくたそ無料写真素材を使用しております。ありがとうございます! http://www.pakutaso.com/about.html
.Ţ�½¥Ƅŕ�
13年7月28日日曜日
R ±Â²Ä�Ä Ƭ�
Q ªÄ¦²Ä� Ƭ�
Q ŏ�Ŏ`²Ä� Ƭ�
R ¥¶£º¿ Ƭ� ùƁƪJ� wlơ
Ö\�f�z}ŘƞÔ�x`
13年7月28日日曜日
R ±Â²Ä�Ä Ƭ�
Q ªÄ¦²Ä� Ƭ�
Q ŏ�Ŏ`²Ä� Ƭ�
R ¥¶£º¿ Ƭ� ùƁƪJ� wlơ
Ö\�f�z}ŘƞÔ�x`
���¸°»ÄŹ~8@=<Ä©õĜ
���Ć`z²Ä��ƕĩl�x ��ùƁƗƠ_ä��
13年7月28日日曜日
$(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){
f�zģkwĹZr�[dy���
8@=<Ä©õĜĥìãŔ{m�m�ãŔ�ĹZr�[
Ä©�2=;�6A;:�}È{ÙĬjr�[
13年7月28日日曜日
ŠZ[r~ZZ}wldy
q�q�xƙbzsv
13年7月28日日曜日
\sŤ}�į ªºƓa���ŵå}�įw�
yf{Ò_ĹZvY�^
ğ�vj�Z�l����|
ぱくたそ無料写真素材を使用しております。ありがとうございます! http://www.pakutaso.com/about.html
13年7月28日日曜日
o}x`TäÐspľơ
�/C/(1?7>A�"+�wơ½�³½¾~�/190=<3�8@_�heơ
13年7月28日日曜日
hsob"+��Ƈ�v��jpU
13年7月28日日曜日
MVCの構造[編集]
MVCでは、プログラムを3つの要素、Model(モデル)、View(ビュー)、Controller(コントローラ)に分割する。
Modelそのアプリケーションが扱う領域のデータと手続き(ビジネスロジック - ショッピングの合計額や送料を計算するなど)を表現する要素である。また、データの変更をviewに通知するのもmodelの責任である(modelの変更を通知するのにObserver パターンが用いられることもある)。多くのアプリケーションではデータの格納に永続的な記憶の仕組み(データベースなど)が使われている。MVCの概念では、データの(UI以外の)入出力は取り扱わないので、データアクセスも本来MVCの概念の範疇を超えるものではあるが、敢えていえばmodelの中に隠蔽されると考えられる。Viewmodelのデータを取り出してユーザが見るのに適した形で表示する要素である。すなわちUIへの出力を担当する。例えば、ウェブアプリケーションではHTML文書を生成して動的にデータを表示するためのコードなどにあたる。Controllerユーザの入力(通常イベントとして通知される)に対して応答し、それを処理する要素である。すなわちUIからの入力を担当する。modelとviewに変更を引き起こす場合もあるが、直接に描画を行ったり、modelの内部データを直接操作したりはしない。
http://ja.wikipedia.org/wiki/Model_View_Controller
���¶��w"+��Ƈ��x���
13年7月28日日曜日
z�q^å^sp�[z
å^�zZ�[zģkz}wldy
f�zģkwÔsv��jpU
13年7月28日日曜日
�=<A?=::3?
"=23:
+73D
��+73D_"=23:âċ�Źš
APIサーバ��"=23:_¡Ä²��¸°»ÄŹ�8@=<Ä©wõĜ
.]��Ą�sp���
GET
Ä©x¼Ä¢}İÔxįŘ}ƛØ
13年7月28日日曜日
click!
�=<A?=::3?
"=23:
+73D
���=<A?=::3?_"=23:�Ąĸ
��+73D_"=23:âċ�Źš
APIサーバ��"=23:_¡Ä²��¸°»ÄŹ�8@=<Ä©wõĜ
��+73D_¼Ä¢İÔ�ödõ� ��+73D_"=23:âċ�Źš
.]��Ą�sp���
.ƀ��p��
.]��Ą�sp���
GET
Ä©x¼Ä¢}İÔxįŘ}ƛØ
13年7月28日日曜日
ApplicationViewアプリケーション全体表示を管理
MenuItemViewメニュー表の1行表示を管理
MenuListViewメニュー表全体表示を管理
SumPriceView合計金額表示を管理
+73D}åê~P}�[{j�[xĠZ�lU
13年7月28日日曜日
f�z�)"!ŖĢj�jpU
<div id="application" >
<h1 class="menu-title" > メニュー表 </h1> <table id="menu-table" > </table> <div id="sum-price-pane" > <script id="sum-price-pane-template" type="text/template" > 合計:<span ><%= sumPrice %></span>
</script> </div></div>
13年7月28日日曜日
w~�/190=<3�8@}ńŴ�Õsv
Ôsv��j�[ơ
13年7月28日日曜日
Ïǽ�³½¾_ĞƟwlUS*<23?@1=?3�8@T�8&B3?F�ó~�-3>A=
Ò_×èz}ƫSŘƞ�×è{Ôĥl��Â¥®½�©ƛIJ_Spbh�Y��lUSS��/190=<3��C3<A@SS��/190=<3�"=23:SSS��/190=<3��=::31A7=<SS��/190=<3�+73D������Î{�pbh�
Sf���ŮħjvÔ�ÊwÅĉ}¿Ä¿wƂƐl�Ê_äŀ�lU���Â¥®½�©ƛIJx~T�³¤��®�ŕĥl�ƛIJw���½¥}�[z�}wlU
�/190=<3�8@{tZv
13年7月28日日曜日
var object = {};
_.extend(object, Backbone.Events);
object.on("alert", function(msg) { alert("Triggered " + msg);});
object.trigger("alert", "an event");
ő{�/190=<3��C3<A@~×èơ
�/190=<3�8@}øńŴ~�C3<A@�ŮħjvZ�ŌTŵÔ�µÂ®�ŚŊxöÚ_w`��[{zsvZ�lU
http://backbonejs.org/
Underscore.jsの機能:オブジェクトのすべてのプロパティを別オブジェクトにコピー
13年7月28日日曜日
�C3<A
�/190=<3�"=23:�/190=<3��=::31A7=<
�C3<A
�$"Žũ�6A;:�
�/190=<3�+73D
"=23:}Ąĸ�+73D{ôĶl��µÂ®wÕ\�lơ
�=<A?=::3?"=23:
+73D
.3C3<A�47?3��.3C3<A�47?3��
�$"ŽũŚŕ�µÂ®�ŝſ��/190=<3�+73D�3C3<A@
øńŴ��C3<AūŗwĮůw`�lơ
"=23:Ąĸ�µÂ®�ŝſ�/190=<3�+73D�:7@A3<)=
13年7月28日日曜日
�m~ÃÃÃ"+�}"}ÃÃ
"=23:^�ÔsvZ`�lơ
13年7月28日日曜日
¸°»ÄÄ©�Źœjv��lơ
"+�}"=23:��/190=<3�"=23:x�/190=<3��=::31A7=<wŹœjv��lU
�/190=<3�"=23:~93FC/:B3ā}Ä©�ĬtÊ_w`+73D{ƒşl�Ō}�µÂ®�Śŕl�Ê_äŀ�lU
�/190=<3��=::31A7=<~ŻIJ}"=23:�Łŧl�Ê_äŀ�lU
�/190=<3�"=23:��=::31A7=<�ĭĉÞ^�8@=<Ä©�õĜjŵïwŁŧl�Ê_äŀ�lU
93F C/:B393F C/:B3
�/190=<3�"=23:
.3C3<A�47?3��
�/190=<3��=::31A7=<
�/190=<3�"=23:�/190=<3�"=23:
13年7月28日日曜日
"=23:w¸°»ÄÄ©�Źœ
var MenuItem = Backbone.Model.extend({
defaults:{
checked: false, //:boolean 選択フラグ
name: "", //:string ハンバーガー名
price: 0 //:number お値段
},
toggleChecked: function(){
this.set("checked", !this.get("checked") );
}
})
¹¿Ďġ}çĽÜ
<3D��Â¥©Â¥ŕĥ�ķ{çĽƃĉh��ÜU
"=23:�53A�L93FûM�wõĜT�"=23:�@3A�L93FûMMÜM�wƃĉj�lU
O�"=23:�@3Aķ{�L16/<53M�µÂ®_47?3h��lơ�
�/190=<3�ńŴ£¾Ä¦��Ůħ�īĘ�3EA3<2�jp�}{ŵ鸨«¯�Ƒíw`�lU
f}Öw~TƕĩÃƝƕĩŒĤ}æ帨«¯��ƑíjvZ�lU
�/190=<3�"=23:�īĘjv
"3<B�A3;�Â¥®½�©ƛIJ�ŕĥ
13年7月28日日曜日
�%�¡Ä²{ƖűjvZ�8@=<~f�zģkwlU
[ { "name": "ハンバーガ", "price": 300 }, { "name": "チーズバーガ", "price": 400 }, { "name": "照り焼きバーガ", "price": 500 }, { "name": "スペシャル", "price": 600 }]
http://jsrun.it/assets/a/6/2/V/a62Vk
13年7月28日日曜日
�=::31A7=<w"=23:�Ŀ|�lU
var!MenuList!=!Backbone.Collection.extend({
!!!!model:!MenuItem,
!!!!url:!'/assets/a/6/2/V/a62Vk',
!!!!sumPrice:!function(){
!!!!!!!!var!checkedMenuItems!=!this.where({!checked:true!});
!!!!!!!!var!sum!=!0;
!!!!!!!!_.each(checkedMenuItems,function(model){
!!!!!!!!!!!!sum!+=!model.get("price");
!!!!!!!!});
!!!!!!!!return!sum;
!!!!}
});
Łŧ"=23:U�($#Ü�ŵïwƃĉw`�lơ×èơ
Ãŵ鸨«¯�ƕĩƗƠƜƁ¸¨«¯�
�=::31A7=<�D63?3{vŵå_ĬsvZ�¹¿�ŭ�Ǝ�Ê_w`�lU
�/190=<3��=::31A7=<�īĘO��=::31A7=<xZ[ûéwldy"+�}"wlU
�($#Ü}õĜÝ
13年7月28日日曜日
Ņ~"+�}UUU
�=<A?=::3?x+73D���Y�sÅŰ{ƫƫ
13年7月28日日曜日
Backbone.jsの ViewはControllerの機能も持ちます!
ご注意!
z�w+73Dx�=<A?=::3?_å^�vzZ^Ɔ^ı\vơ
13年7月28日日曜日
�C3<A
�/190=<3�"=23:�/190=<3��=::31A7=<
�C3<A
�$"Žũ�6A;:�
�/190=<3�+73D
źƍƪ��/190=<3�+73D���+73D����=<A?=::3?
�=<A?=::3?"=23:
+73D
.3C3<A�47?3��.3C3<A�47?3��
o�o�"+�wō^sp�l�}^zX���
13年7月28日日曜日
�/190=<3�+73DwŘƞŹœơ
�/190=<3�+73D~�/190=<3�"=23:��=::31A7=<�ÙĬj�lU�pT�/190=<3�"=23:��=::31A7=<}Ąĸ�µÂ®öÚ_÷ŴwTo}ĄĸÄ©�Ý{įŘl�Ê_w`�lU
�/190=<3�+73D
.3C3<A�47?3��
�/190=<3��=::31A7=<
�/190=<3�"=23:�/190=<3�"=23:
�/190=<3��=::31A7=<
òŏ�Ĭsv�l
13年7月28日日曜日
var!MenuItemView!=!Backbone.View.extend({
!!!!tagName:!'tr',!//:<tr></tr>
!!!
!!!!initialize:!function(!options){
!!!!!!!!var!menuItem!=!this.model;!//:MenuItem
!!!!!!!!this.listenTo(!menuItem,!'change',!this.updateRender);
!!!!},
!!!!createRender:!function(){
!!!!!!!!var!menuItem!=!this.model;
�/190=<3�+73Dw¸°»ÄŹ��ŷ��Źœ
+73D}çĽð�7<7A7/:7G3�¸¨«¯<3D�"3<B�A3;�H;=23:�EEI�w�A67@�;=23:��ƃĉw`�lU:7@A3<)={v�"=23:}Ąĸ�µÂ®ŝſ�ĉŲjvZ�lU
�/190=<3�+73D~ÉzŦŔ�$"Žũ�Ĭr�lU
A/5#/;3�ĭĉjpĂùTijž�$"Žũ�ŕĥjŦŔČƉxj�lU
13年7月28日日曜日
!!!!!!!!this.listenTo(!menuItem,!'change',!this.updateRender);
!!!!},
!!!!createRender:!function(){
!!!!!!!!var!menuItem!=!this.model;!//:MenuItem
!!!!!!!!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"
!!!!},
+73Dw¸°»ÄŹ��ŷ��Źœ
+73D{Ũudp"=23:~
Ztw�A67@�;=23:wÕ\�lU
A67@��3:{ŦŔjvZ�
8&B3?FŽũ_ß��lU
���ŵ鸨«¯
ffw~çĽįŘ�ĉŲjv�lU
����µÂ®}śƘ
��A67@��3:wŚŕjp�µÂ®{
��+73D¸¨«¯�Ũud�lU
13年7月28日日曜日
!!!!!!!!!!!.append($('<td>').text(price));!!!!},!!!!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);!!!!!!!!if!(!checked!){!!!!!!!!!!!!this.$el.addClass('on');!!!!!!!!}else{!!!!!!!!!!!!this.$el.removeClass('on');!!!!!!!!}!!!!}});
+73Dw¸°»ÄŹ��ŷ��Źœ
Ãŵ鸨«¯�¸°»ÄĪÇãŔ�
"=23:}¸¨«¯�ý�äjvZ�lU
O�ŞĮįŘjzZfxơ
ŵ鸨«¯�¹¿Ąĸ�ôĶl�¸¨«¯�this.listenTo( menuItem, 'change', this.updateRender);
13年7月28日日曜日
var MenuListView = Backbone.View.extend({ el:'#menu-table', initialize: function(options){ this.listenTo(this.collection, //:MenuList '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); }});
+73Dw¸°»ÄŹ�Źœ���+73D_ŦŔl�Žũ�§À�©wĭĉw`�lU
����($#Ä©õĜķ{ŚŊl�?3@3A�µÂ®w:7@A'3<23?�Ƌïj�lU
���"=23:}IJ帨«¯�ý��lU
���ėIJ{"=23:_ß��lU
����ŷå}+73D�ŕĥjv¬Ä³¿+73D{Łŧj�lU
13年7月28日日曜日
var SumPriceView = Backbone.View.extend({
el: '#sum-price-pane',
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 );
}
});
+73DwùƁ�Źœ
A3;>:/A3ƛIJ�ŕĥ
A3;>:/A3ƛIJ�Ċŷơ
"3<B!7@A�ŝſ
13年7月28日日曜日
<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>
+73DwùƁ�Źœ�A3;>:/A3}ÕZĴ
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月28日日曜日
+73DwùƁ�Źœ�A3;>:/A3}ÕZĴ���
_.templateSettings = {
evaluate: /\{%(.+?)%\}/g,
interpolate: /\{\{(.+?)\}\}/g,
escape: /\{%-(.+?)%\}/g
};
ちなみに<%= value %>が使えない環境の場合は。。
ÆƂ}ÖqxÏÇ}�[zĹĖ{æ�ĺ���ơ
H���/C/(1?7>A��I
HH�o}��äë�II
H���¥�Ä´jväë��I
13年7月28日日曜日
Ļě{�´¾àÑ�+73DwÔsväŀÆ_�ơ
var ApplicationView = Backbone.View.extend({ el: '#application', 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月28日日曜日
�x���VŶZĦW
N�µÂ®ūŗ�èŖjvřŬù{Ĺ`�lZ
�"=23:~+73D}ĈĀ�j�zZT(B0+73Dúă_ĈĀ�ş�zZƢ
NĚêxĹbĂĦ_ň�svZ�}wÎË}¨Ä¥�`sxƅ��lZ
~mU
VŇ{zspŋW
N+73D�z��bčhbĝ_dzZxTlc{đąðjvj�[U
Nr�sxjp´Á�½·}ĂùTçĽ}ĐIJ_ÓƁ{^^�^�U
13年7月28日日曜日
ÈžŃÏÆ}�/C/(1?7>AƚŚ{~��� �$#���(}�[z½�³½¾�Õsv
łjbƚŚjpZ�}wl|U
13年7月28日日曜日
Ɗþ~giZ�l^ƫƫ
13年7月28日日曜日
¡Â´¿~fr�{áƚjv]��l
http://jsdo.it/itoKami1123/aPmk/
]j�Z
Y�_x[giZ�jpơ
13年7月28日日曜日