2012-03-20 25 views
12

Tôi muốn biết nếu có cách nào tốt hơn để tạo nhiều bộ sưu tập tìm nạp từ một tệp JSON lớn duy nhất. Tôi nhận được một tệp JSON trông như thế này.Backbone nhiều bộ sưu tập tìm nạp từ một tệp JSON lớn duy nhất

{ 
    "Languages": [...], 
    "ProductTypes": [...], 
    "Menus": [...], 
    "Submenus": [...], 
    "SampleOne": [...], 
    "SampleTwo": [...], 
    "SampleMore": [...] 
} 

Tôi đang sử dụng url/fetch để tạo mỗi bộ sưu tập cho mỗi nút của JSON ở trên.

var source = 'data/sample.json'; 

Languages.url = source; 
Languages.fetch(); 

ProductTypes.url = source; 
ProductTypes.fetch(); 

Menus.url = source; 
Menus.fetch(); 

Submenus.url = source; 
Submenus.fetch(); 

SampleOne.url = source; 
SampleOne.fetch(); 

SampleTwo.url = source; 
SampleTwo.fetch(); 

SampleMore.url = source; 
SampleMore.fetch(); 

Bất kỳ giải pháp nào tốt hơn cho điều này?

Trả lời

18

Xương sống là điều tuyệt vời khi ứng dụng của bạn phù hợp với khuôn mà nó cung cấp. Nhưng đừng ngại đi xung quanh nó khi nó có ý nghĩa cho ứng dụng của bạn. Đó là một thư viện rất nhỏ. Thực hiện lặp lại và lặp lại yêu cầu GET chỉ để phù hợp với khuôn xương sống có lẽ là không hiệu quả. Kiểm tra jQuery.getJSON hoặc thư viện AJAX cơ bản yêu thích của bạn, kết hợp với một số lập trình meta cơ bản như sau:

//Put your real collection constructors here. Just examples. 
var collections = { 
    Languages: Backbone.Collection.extend(), 
    ProductTypes: Backbone.Collection.extend(), 
    Menus: Backbone.Collection.extend() 
}; 

function fetch() { 
    $.getJSON("/url/to/your/big.json", { 
     success: function (response) { 
      for (var name in collections) { 
       //Grab the list of raw json objects by name out of the response 
       //pass it to your collection's constructor 
       //and store a reference to your now-populated collection instance 
       //in your collection lookup object 
       collections[name] = new collections[name](response[name]); 
      } 
     } 
    }); 
} 

fetch(); 

Khi bạn đã gọi fetch() và gọi lại asyn đã hoàn thành, bạn có thể làm những việc như collections.Menus.at(0) để có được vào mô hình được tải trường hợp.

+0

Ha! Những đầu óc vĩ đại. – nrabinowitz

+0

Tuyệt vời! Simulanswer! –

14

Cách tiếp cận hiện tại của bạn, ngoài việc khá dài, rủi ro truy xuất tệp lớn nhiều lần (bộ nhớ đệm trình duyệt sẽ không hoạt động ở đây, đặc biệt nếu yêu cầu đầu tiên không hoàn thành theo thời gian bạn thực hiện tiếp theo) .

Tôi nghĩ là lựa chọn dễ dàng nhất ở đây là để đi với jQuery thẳng, chứ không phải là Backbone, sau đó sử dụng .reset() vào bộ sưu tập của bạn:

$.get('data/sample.json', function(data) { 
    Languages.reset(data['Languages']); 
    ProductTypes.reset(data['ProductTypes']); 
    // etc 
}); 

Nếu bạn muốn giảm bớt các mã không cần thiết, bạn có thể đặt bạn bộ sưu tập lại trong một namespace như app và sau đó làm một cái gì đó như thế này (mặc dù nó có thể là một chút quá thông minh để dễ đọc):

app.Languages = new LanguageCollection(); 
// etc 

$.get('data/sample.json', function(data) { 
    _(['Languages', 'ProductTypes', ... ]).each(function(collection) { 
     app[collection].reset(data[collection]); 
    }) 
}); 
4

Bạn có thể dễ dàng làm điều này với một phương pháp phân tích cú pháp. Thiết lập mô hình và tạo thuộc tính cho từng bộ sưu tập. Không có gì nói thuộc tính mô hình của bạn phải là một phần dữ liệu duy nhất và không thể là một bộ sưu tập.

Khi bạn chạy tìm nạp, nó sẽ trả về toàn bộ phản hồi cho phương thức phân tích cú pháp mà bạn có thể ghi đè bằng cách tạo hàm phân tích cú pháp trong mô hình của mình. Một cái gì đó như:

parse: function(response) { 
    var myResponse = {}; 
    _.each(response.data, function(value, key) { 
     myResponse[key] = new Backbone.Collection(value); 
    } 

    return myResponse; 
} 

Bạn cũng có thể tạo ra bộ sưu tập mới ở mức độ toàn cầu hoặc vào một số không gian tên khác nếu bạn không muốn có chúng chứa trong một mô hình, nhưng đó là tùy thuộc vào bạn.

Để có được chúng từ các mô hình sau này bạn muốn chỉ phải làm một cái gì đó như:

model.get('Languages'); 
+0

Máy chủ của chúng tôi cung cấp cho tôi các đối tượng lồng nhau ồ ạt khi tôi không phân tích cú pháp và thêm vào bộ sưu tập nếu cần. – tkone

6

Tôi nghĩ rằng bạn có thể giải quyết nhu cầu của bạn và vẫn nghỉ vào Backbone mô, tôi nghĩ rằng một giải pháp thanh lịch phù hợp với tôi là tạo ra một Model rằng fetch các JSON lớn và sử dụng nó để fetch tất cả các Collections trong change sự kiện của nó:

var App = Backbone.Model.extend({ 
    url: "http://myserver.com/data/sample.json", 

    initialize: function(opts){ 
    this.languages = new Languages(); 
    this.productTypes = new ProductTypes(); 
    // ... 

    this.on("change", this.fetchCollections, this); 
    }, 

    fetchCollections: function(){ 
    this.languages.reset(this.get("Languages")); 
    this.productTypes.reset(this.get("ProductTypes")); 
    // ... 
    } 
}); 

var myApp = new App(); 
myApp.fetch(); 

Bạn có quyền truy cập vào tất cả các bộ sưu tập của bạn thông qua:

myApp.languages 
myApp.productTypes 
... 
+0

Trong khi mô hình trừu tượng là khá hấp dẫn, tôi không thích cách tiếp cận này. Dữ liệu sẽ không bao giờ được lưu trữ trong cấu trúc hiện tại của nó ... nó sẽ được chia thành các bộ sưu tập khác nhau. Bạn cũng có thể sử dụng .json(). Mục đích của một mô hình là để lưu trữ 'một cái gì đó' phải không? – backdesk

0

xương sống quan hệ cung cấp một giải pháp trong xương sống (không sử dụng jQuery.getJSON) mà có thể có ý nghĩa nếu bạn đã sử dụng nó. Câu trả lời ngắn gọn tại số https://stackoverflow.com/a/11095675/70987 mà tôi rất vui được xây dựng nếu cần.

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