Backbone.js emulateHTTP and emulateJSON

Backbone.emulateHTTP值為true時,會模擬restful的動作,將delete和put(update) method,全部都用post method代替,然後添加X-HTTP-Method-Override的header和_method的參數。

Example如下:

先建立一個Book Model。

Backbone.emulateHTTP = true;
Backbone.emulateJSON = true;
var Book = Backbone.Model.extend({
  urlRoot:"/books"     
});                      
var book = new Book({id:32});

執行save時,會發送request到server。(在backbone的model id有值的時候,save會是update功能,反之則為create。)

                                                                                                                                                                                            
book.save({name:"Tom"}); 

發送request到server端的header,會添加以下這段:

X-HTTP-Method-Override:PUT

Backbone.emulateJSON為true時,request的content-type會設定為application/x-www-form-urlencoded,傳遞到server參數如下:

model={"id":32,"name":"Tom"}&_method=PUT

Backbone.emulateJSON為false時,request的content-type會設定為application/json,傳遞到server參數如下:

{"id":32,"name":"Tom"}

所以當request的content-type不是application/json時,使用emulateHTTP,會多傳一個_method的參數到server端,可供server辨識。

Backbone history

backbone的router,主要用途是可以依照不同url,做不同的動作,很適合拿來做動態頁面切換,像是拿來製作mobile web,就滿適合的,使用到的技術有兩種,一個是利用錨點(#)的特性,另一個則是使用html5的pushState,達到不換頁的效果。

以下是官方的範例:

var Workspace = Backbone.Router.extend({

  routes: {
    "help":                 "help",    // #help
    "search/:query":        "search",  // #search/kiwis
    "search/:query/p:page": "search"   // #search/kiwis/p7
  },

  help: function() {
    doSomething("help");
  },

  search: function(query, page) {
    doSomething( query, page );
  }

});

定義好router要做的事情後,接著把router實體化:

new Workspace()

最後執行start,router就能開始運作了:

/**
* 開始使用router
* @param {String} root 指的是起始url
* @param {object} opts.pustState 就是html的pushState,如果為true就不會採用錨點方式,而是直接更動url,讓web看到在不同頁面的url
*/
Backbone.history.start({root:"/"});

/**
* 更動web上的location url
* @param {String} url
* @param {Object} opts.trigger 為true,則會觸發router event,如果為false,只會更動location url
* @param {Object} opts.replace 為true,會取代目前這筆的history,pushState則是新增一筆
*/
Backbone.history.navigate("/search",{trigger:true});

用錨點的優勢,支援舊有的瀏覽器(backbone都處理好了,即時不支援pushState,也會採用錨點方式),也可以直接利用a這個element,直接觸發event,而不需在另外寫script去bind event。如下:

<a href="#search">search</a>

利用pushState想達到跟錨點一樣的效果,可以如下:

$(document.body).on( "click", "a.history-go" ,function( event ){
    Backbone.history.navigate( $(this).attr("href").replace("#","") ,{trigger:true} );
    event.preventDefault();
}).on( "click", "a.history-back" );

接著只要在a這個Element,加入class,即可達到一樣效果:

<a class="history-go" href="#search">search</a><br>
<a class="history-back">back</a>