Slide 1

Slide 1 text

Backbone.js in Action 大澤木小鐵 @ JavaScript.TW Group

Slide 2

Slide 2 text

Backbone.js 簡介。 Backbone.js 開發基本要點。 如何整合 RequireJS 。 可能會出糗的 Live Demo 。 Agenda 不知道穿紅內褲會不會有保佑?

Slide 3

Slide 3 text

無法介紹詳細的 API 用法。 Live Demo 無法涵蓋所有 API 。 例子可能有點無聊。 預防針 http://speakerdeck.com/u/jaceju/p/head-first-backbonejs 講者另一個介紹 API 的 slide 網址

Slide 4

Slide 4 text

因為講者背骨 為什麼用

Slide 5

Slide 5 text

輕巧 壓縮後的檔案大小僅 5.6kb 。 靈活 不需用到所有 Backbone 類別。 學習容易 會 jQuery 就可以了。

Slide 6

Slide 6 text

Backbone 基本類別 Sync View Event History extend use Router Model Collection

Slide 7

Slide 7 text

Model Router View URL Data Status DOM Template 關注點分離 解耦很重要

Slide 8

Slide 8 text

類別行為 Event – 讓非 DOM 物件也能有自訂事件。 Model – 存取 Data ,可用 AJAX 或 LocalStorage 。 Collection – Model 的集合。 View – 接收輸入或更新 UI 。 Router – 控制網址,並處理 Model 與 View 的互動。

Slide 9

Slide 9 text

上路需知 要先載入 underscore.js 。 可以只用 Event 、 Model 或 View 。 使用 View 時,要搭配 DOM Library 。 資料同步不⼀一定要用 Database 。

Slide 10

Slide 10 text

基本流程 定義 UI 及 Template 。 定義 View 及事件。 定義 Model 。 定義 App Router 。 整合所有類別。 執行程式。

Slide 11

Slide 11 text

程式碼 基本形式 不見得是最好的做法 要多看一些高手寫的範例

Slide 12

Slide 12 text

index.html ... ... 通常一個 template 會對應一個 View

Slide 13

Slide 13 text

Router var App = Backbone.Router.extend({ initialize: function () { }, routes: { '': 'home', 'hash1': 'action1', 'hash2/:id': 'action2' }, home: function () {}, action1: function () {}, action2: function (id) {} }); 記得要寫 routes ,這樣 Router 初始化時 才會建立 Backbone.history 物件 http://documentcloud.github.com/backbone/#Router

Slide 14

Slide 14 text

Model var Model = Backbone.Model.extend({ defaults: { id: null, attr1: '', attr2: '' }, validate: function(attrs) { if (attrs.attr1 === '') { return "'attr1' cannot be empty"; } if (attrs.attr2 === '') { return "'attr2' cannot be empty"; } } }); 驗證未通過時,會觸發 error 事件

Slide 15

Slide 15 text

Collection var Collection = Backbone.Collection.extend({ model: Model }); 注意 model 屬性是指向 Model 類別 而不是 Model 物件

Slide 16

Slide 16 text

View var View = Backbone.View.extend({ template: _.template($('#view-template').html()), render: function () { this.$el.html(this.template(this.model.toJSON())); return this; }, events: { 'click selector': 'callback' }, callback: function (e) { } }); 注意 template 屬性在這裡 是一個 template engine

Slide 17

Slide 17 text

初始化 Collection var App = Backbone.Router.extend({ collection: null, initialize: function () { this.collection = new Collection(); this.collection.fetch(); }, // ... initialize 方法只會在應用程式開始時執行一次 所以初始化 collection 後的 fetch 方法也只會執行一次

Slide 18

Slide 18 text

整合 Model 與 View var App = Backbone.Router.extend({ // ... action: function () { var model = new Model({ attr1: '', attr2: '', }); var view = new View({ model: model, collection: this.collection }); $('#container').empty().append(view.render().el); }, // ... 在 View 初始化時 在 model 或 collection 屬性 帶入對應的 model 或 collection 物件

Slide 19

Slide 19 text

執行 $(function () { new App(); Backbone.history.start(); }); 因為 View 有用到 DOM 元素 所以要在 DOM Ready 後執行

Slide 20

Slide 20 text

RequireJS

Slide 21

Slide 21 text

index.html ... ... data-main 所指向的 js 檔案 就是我們主要的程式進入點

Slide 22

Slide 22 text

main.js require({ baseUrl: './', paths: { order: 'lib/requirejs/order', text: 'lib/requirejs/text' }, }); require([ 'order!lib/jquery/jquery-min', 'order!lib/underscore/underscore-min', 'order!lib/backbone/backbone-min', 'order!bootstrap/js/bootstrap.min', 'order!js/app', ], function () { App = _.last(arguments); App.initialize(); }); 其他的 callback 參數是我們不需要的 所以利用 arguments 取得最後一個參數

Slide 23

Slide 23 text

app.js define([ 'js/router/Router' ], function (Router) { return { initialize: function () { var router = new Router; Backbone.history.start(); } } }); 注意 callback 回傳的是 只包含一個 initialize 方法的物件

Slide 24

Slide 24 text

Router define([ 'js/model/Model', 'js/view/View', ], function (Model, View) { return Backbone.Router.extend({ // ... }); }); Model 與 View 沒有載入順序的問題

Slide 25

Slide 25 text

Model & Collection define(function () { return Backbone.Model.extend({ // ... }); }); define([ 'js/model/Model' ], function (Model) { return Backbone.Collection.extend({ model: Model }); }); Collection 一定會相依 Model

Slide 26

Slide 26 text

Main View & SubView define([ 'text!template/sub.html' ], function (view_template) { return Backbone.View.extend({ // ... }); }); define([ 'js/view/SubView', 'text!template/main.html', ], function (SubView, view_template) { return Backbone.View.extend({ // ... }); }); 改用 text plugin 載入 template 就不用在 index.html 使用 script 來包覆 template 而且可以在最佳化時把 template 變成內建字串

Slide 27

Slide 27 text

Live Demo https://github.com/jaceju/backbone_in_action 完整範例的網址

Slide 28

Slide 28 text

Q & A 沒有最好的 MV* Framework 只有適合專案使用的 MV* Framework