2012-04-28 54 views
7

在backbone.js中,您必須手動設置每個模型的rooturl。有沒有辦法讓我們在一個地方設置一次,所有模型都會使用它?在Backbone.js應用程序中設置全局REST根URL

例如, api.site.com將是REST服務,但出於測試目的,它可能在localhost:1000我需要能夠輕鬆更改服務的根網址,而不是將它們放在應用程序中存在的許多模型中。

回答

2

不確定您的意思是什麼意思手動爲每個模型設置urlRoot。 想必你做

var MyModel = Backbone.Model.extend({ 

    urlRoot: '/mymodel', 
    ... 

}); 

對不對?那麼每個模型實例自然具有相同的urlRoot。說MyOtherModel的任何其他模型實例將具有一些不同的urlRoot

如果由於某種原因您需要使用相同的urlRoot,我想這應該是因爲模型共享屬性。這應該暗示繼承或擴展,所以你可以這樣做:

var BaseModel = Backbone.Model.extend({ 
    urlRoot: '/mymodel' 
}); 

var MyModel = BaseModel.extend({ 
    ... 
}); 
8

我的理解是:

你有幾種模式:模型1和模型2

根URL可以是http://api.site.comhttp://localhost:8080根據無論您是在本地還是外部工作。然後有一天,它可能是http://api.anothersite.com

我會做財產以後這樣便:

// Global var before any other JS code, you comment line depending on which one applies 
var ROOT = 'http://api.site.com' 
// var ROOT = 'http://localhost:8080' 

var Model1 = Backbone.Model.extend({ 
urlRoot: ROOT+'/model1', 
... 
}); 

var Model2 = Backbone.Model.extend({ 
urlRoot: ROOT+'/model2', 
... 
}); 

但要小心,你可能會忘記commiting時從一個URL切換到另一個。更好的辦法是處理相對路徑,如果他們適用。

12

我一直在玩最優雅的方式來使用Backbone與AMD(require.js)。這就是我想到的,並且最好[迄今]。

首先,引導數據,如here所述。

的index.htm(應用進入點)

<!DOCTYPE html> 
<head> 
    <meta charset="utf-8"> 

    <script> 
    var require = { 
     config: { 
     // key name is module, value is data to give module 
     'models/Base': { 
      apiUrl: '/some/path/to/api', 
     } 
     } 
    } 
    </script> 
<script data-main="js/main" src="vendor/require/require-jquery.js"></script> 
</head> 
<body></body> 
</html> 

接下來,定義基類爲骨幹模型,如下:

JS /模型/ Base.js(注意這個模塊名稱與上面配置中的模塊名稱相匹配)

define(['module', 'backbone'], 
    function(module, Backbone){ 

    return Backbone.Model.extend({ 
     getApiUrl: function(){ 
     return module.config().apiUrl; 
     } 
    }); 

    } 
); 

最後,將所有從這個基準,這樣你的骨幹機型:

JS /模型/ user.js的

define(['models/Base'], 
    function(BaseModel){ 

    return BaseModel.extend({ 
     urlRoot: function(){ 
     return this.getApiUrl() + '/user'; 
     } 
     // ... more cool stuff here 
    }); 

    } 
); 

這是對於骨幹網和Require.JS切向相關的earlier question I had

相關閱讀:http://requirejs.org/docs/api.html#config-moduleconfig

0

剛剛從'/'開始您的網址。 因此,您不會依賴本地主機或真實域。

2

在我看來,最好的方法是覆蓋Backbone.sync方法,並在其中加上根URL。這是因爲知道API域不是模型的責任。

// Cache Backbone.sync for later use 
var sync = Backbone.sync; 
Backbone.sync = function(method, model, options){ 
    options.beforeSend = function(){ 
    this.url = API_ROOT_URL + this.url; 
    }; 
    return sync.call(this, method, model, options); 
}; 

然後你就可以創建你的模型,你通常會做:

var Resource = Backbone.Model.extend({ 
    urlRoot: '/resources', 
}); 

我使用同樣的方法追加一個.json擴展到所有的URL通過瀏覽器緩存,以防止JSON閃爍。

+0

我不認爲這個工程。 'beforeSend()'在用原始URL打開請求之後調用。 – mwhite 2016-01-26 21:06:53

+0

這正是'beforeSend'的用法; * beforeSend類型:函數(jqXHR jqXHR,PlainObject設置)一個預先請求的回調函數,可用於在jqXHR(jQuery 1.4.x,XMLHTTPRequest)對象發送之前修改它。使用它來設置自定義標題等.jqXHR和設置對象作爲參數傳遞。這是一個Ajax事件。在beforeSend函數中返回false將取消請求。從jQuery 1.5開始,beforeSend選項將被調用,而不管請求的類型如何。* – 2016-01-26 21:14:31

+0

它是在請求被髮送之前,但在被初始化之後(使用現有的url)。我的答案正常工作。 – mwhite 2016-01-26 21:18:52

2

https://coderwall.com/p/8ldaqw/add-a-root-url-to-all-backbone-api-request

var backboneSync = Backbone.sync; 

Backbone.sync = function (method, model, options) { 
    /* 
    * Change the `url` property of options to begin 
    * with the URL from settings 
    * This works because the options object gets sent as 
    * the jQuery ajax options, which includes the `url` property 
    */ 
    options = _.extend(options, { 
     url: API_ROOT + _.result(model, 'url') 
    }); 

    /* 
    * Call the stored original Backbone.sync 
    * method with the new url property 
    */ 
    backboneSync(method, model, options); 
}; 
0

這是真的老了後改編,但我認爲我的版本可以成爲有用的人。我使用require.js和我的服務器端和客戶端完全分開的主幹。我給知道客戶端應用,在那裏是在同一時間API根,當我宣佈requirejs腳本:

<script 
    data-main="js/main" 
    data-api-url="https://api/v1/" 
    src="js/require.js"> 
</script> 

,然後我得到了我的骨幹模塊:

var $scriptEl = $('script[data-main]'), 
     base = $scriptEl.attr('data-api-url'); 

var BaseModel = Backbone.Model.extend({ 
    urlRoot: base 
}); 

var model = BaseModel.extend({}); 

這是最優雅的方式,我可以找到..

相關問題