2012-04-28 52 views
7

Trong backbone.js, bạn phải đặt rooturl của mọi mô hình theo cách thủ công. Có cách nào chúng ta có thể thiết lập điều này ở một địa điểm duy nhất một lần và tất cả các mô hình sẽ sử dụng nó?Đặt url gốc REST toàn cầu trong ứng dụng Backbone.js

Ví dụ: api.site.com sẽ là dịch vụ REST, nhưng với mục đích thử nghiệm, nó có thể là localhost:1000 Tôi cần phải có khả năng thay đổi địa chỉ gốc của dịch vụ một cách dễ dàng và không có tất cả các địa điểm trong nhiều mô hình tồn tại trong ứng dụng.

Trả lời

2

Không chắc chắn chính xác ý bạn là thiết lập urlRoot cho mọi mô hình theo cách thủ công. Có lẽ bạn làm

var MyModel = Backbone.Model.extend({ 

    urlRoot: '/mymodel', 
    ... 

}); 

phải không? Sau đó, mỗi trường hợp mô hình tự nhiên có cùng một urlRoot .Bất kỳ trường hợp mô hình nào khác của số MyOtherModel sẽ có một số khác nhau urlRoot.

Nếu vì một lý do nào đó bạn cần phải sử dụng cùng một số urlRoot, tôi cho rằng đó là do các mô hình chia sẻ thuộc tính. Điều này sẽ gợi ý để thừa kế hoặc mở rộng, do đó bạn có thể làm:

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

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

Những gì tôi hiểu là:

Bạn có một số mô hình: MODEL1 và MODEL2

URL gốc có thể là http://api.site.com hay http://localhost:8080 tùy về việc bạn đang làm việc ở địa phương hay bên ngoài. Và một ngày nào đó nó có thể là http://api.anothersite.com

tôi sẽ làm somthing như thế này thì:

// 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', 
... 
}); 

Nhưng hãy cẩn thận với điều này, bạn có thể quên để chuyển đổi từ một url tới một trong những khác khi commiting. Tốt hơn là xử lý các đường dẫn tương đối nếu chúng áp dụng.

12

Tôi đã chơi xung quanh với cách thanh lịch nhất để làm điều này khi sử dụng Backbone với AMD (require.js). Đây là những gì tôi đã đưa ra, và như tốt nhất [cho đến nay].

Trước tiên, hãy khởi động lại dữ liệu trong, như được mô tả here.

index.htm (ứng dụng nhập điểm)

<!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> 

Tiếp theo, xác định một lớp cơ sở cho các mô hình Backbone, như thế này:

js/mô hình/Base.js (chú ý module này tên khớp với tên mô-đun trong cấu hình ở trên)

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

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

    } 
); 

Cuối cùng, mở rộng tất cả mô hình Backbone của bạn từ cơ sở đó, như thế này:

js/mô hình/User.js

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

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

    } 
); 

Đây là tiếp tuyến có liên quan đến một earlier question I had về Backbone và Require.JS.

đọc liên quan: http://requirejs.org/docs/api.html#config-moduleconfig

0

Chỉ cần bắt đầu url của bạn từ '/'. Vì vậy, bạn sẽ không phụ thuộc vào localhost hoặc tên miền thực.

2

Theo tôi, cách tốt nhất để đạt được điều này là bằng cách ghi đè phương thức Backbone.sync và thêm url gốc vào đó. Điều này bởi vì nó không phải là trách nhiệm của mô hình để biết tên miền 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); 
}; 

Và sau đó bạn có thể tạo ra mô hình của bạn như bạn vẫn thường làm:

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

tôi sử dụng phương pháp này tương tự để thêm một phần mở rộng cho tất cả các .json URL để ngăn chặn nhấp nháy JSON thông qua bộ nhớ cache của trình duyệt.

+0

Tôi không nghĩ rằng nó hoạt động. 'beforeSend()' được gọi sau khi yêu cầu đã được mở bằng url ban đầu. – mwhite

+0

Đó chính xác là việc sử dụng 'beforeSend'; * beforeSend Type: Hàm (jqXHR jqXHR, PlainObject settings) Một hàm gọi lại yêu cầu trước có thể được sử dụng để sửa đổi đối tượng jqXHR (trong jQuery 1.4.x, XMLHTTPRequest) trước khi nó được gửi đi. Sử dụng tùy chọn này để đặt tiêu đề tùy chỉnh, v.v. Các đối tượng jqXHR và cài đặt được chuyển làm đối số. Đây là một sự kiện Ajax. Trả về false trong hàm beforeSend sẽ hủy yêu cầu. Kể từ jQuery 1.5, tùy chọn beforeSend sẽ được gọi bất kể loại yêu cầu. * –

+0

Đó là trước khi yêu cầu được gửi nhưng sau khi nó được khởi tạo (với url hiện tại). Câu trả lời của tôi hoạt động chính xác. – mwhite

2

Phỏng theo 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

Đây thực sự là bài cũ, nhưng tôi nghĩ rằng phiên bản của tôi có thể có ích cho một ai đó. Tôi sử dụng xương sống với require.js và phía máy chủ và phía máy khách của tôi được phân tách hoàn toàn. Tôi cho biết cho các ứng dụng client đâu là gốc API cùng một lúc, khi tôi tuyên bố kịch bản requirejs:

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

và sau đó tôi nhận được trong mô-đun xương sống của tôi:

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

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

var model = BaseModel.extend({}); 

Đây là nhất cách tao nhã mà tôi có thể tìm thấy ..

Các vấn đề liên quan