2012年7月5日 星期四

Backbone.js使用RequireJS

一.說明
開發Backbone.js Project,每個Model,View都會是一個個的JS檔案
也會因使用到其他外部Library或是關連到其他Model
而讓各個JS間有一些關聯性
使用RequireJS來將裝Backbone的各個JS檔案都包裝成module,
不僅可以讓每個module切的更乾淨,同時還可利用
RequireJS的Optimizer將所有JS檔案package成單一JS檔案

二.檔案與目錄架構
main.js
app.js
router.js
text.js
order.js
views/
models/
collections/
templates/
libs/    

三.檔案架構說明

  1. main.js : project的進入點
  2. app.js : 初始化App要使用的所有物件instance,與網頁node相對應
  3. router.js : project controller,使用者url經過router處理,呼叫對應要執行的function
  4. text.js與order.js是RequireJS的Plugin,若有用到則放在這裡
  5. views/,collections/,models/ : Backbone產生的各個物件,包成Module後,分別放入各個相關目錄內
  6. templates/ : 要提供給view render使用的html樣板檔案放在這目錄下
  7. libs/ : 會用到的各種外部resource lib放在這裡,如jQuery...


四.main.js
RequireJS的程式進入點是main.js
在main.js內包含了兩個區塊,一塊在做project設定,一塊在做初始要執行的工作

1.設定
設定路徑別名
baseUrl : 設定所有js找檔案的root節點,
          預設是main.js所在路徑,
paths   : 將整個project內會用到的檔案或路徑,
          在這裡設定別名以方便在module中使用,
          使用上以baseUrl下的路徑書寫即可    
urlArgs : 可在runtime時替所有js都加入queryString,
          避免JS Cache

require.config({    
    paths : {    
        _loader:'utils/loader',    
        _$ : 'libs/jquery/jquery',
        _m:'models',        
        ....
    },    
    urlArgs: "ver=0.0",
});

2.要立刻執行的工作
通常會在這個block內,會有兩個部份會被初始化
1.global info
  把在project內屬於多個物件要共同監聽使用的
  model或collection在這裡new出instance,並設定到App內
  讓所有要用到的物件可以參考到
2.App
  整個App的主要架構檔,也在這裡產生instance

require(['order!_$','_Backbone','order!_m/InfoModel','order!_c/StoresCollection','order!_app'],function($,Backbone,InfoModel,StoreCollection,App) {        
    var info=new InfoModel();
    var stores=new StoresCollection();
    var citys=new CityCollection();
    Backbone.emulateHTTP = true;
    Backbone.emulateJSON = true;
    App.initialize({
        info:info,
        stores:stores        
    });        
});


五.Module define定義語法
1.
[]內設定在這Module內要關聯使用的module檔案路徑,在function內則會取到對應的物件可以
在Module內使用
define(['_Underscore','_backbone','_$'],function(_,Backbone,$){
    return {
    
    }
})

2.
在function內帶入require,就可以在module內使用require來載入其他的module
define(function(require){
    var $ = require('_$'),
        _ = require('_Underscore');
    return {
    
    }    
})

六.Module類型-instance模式
當你所定義的module在Project內,需要是一個唯一的singleton
例如App或是Router,在整個專案中都會是只有唯一的一個
次時所定義的Module回傳的會是一個instance而非Backbone Class

1.語法
define([],function(){
    return {
    ....
    }
})
2.Router sample
將原Backbone Router的功能隱藏在自訂的Module內,
定義
XXRouter.js
define([],function(){
   var MyRouter = Backbone.Router.extend({})
   return {
       myRouter: null,
    initialize: function (options) {
        this.myRouter = new MyRouter(options);                
    },
    navigate: function (path) {
        this.MyRouter.navigate("#" + path, true);
    }
}
})
使用
XXRouter.initialize()

3.App Sample
載入後直接取得一個instance物件
定義
App.js
define([],function(){
    return {
        initialize: function (options) {},
        ......
    }
})
使用
App.initialize();


七.Module類型-Class模式
當你所定義的module是屬於Project內的model,view或collection
你所定義的module回傳的會是Backbone的Class
1.語法
App.js
define([],function(){
    return {
       initialize: function (options) {},
        ......
    }
})
2.Backbone View sample
定義
MyView.js
define(['_backbone'],function(Backbone){
    return Backbone.View.extend({
        initialize:function(){},
        .....
    })    
})
使用
var myView=MyView();

沒有留言: