2011-08-03 7 views
9

Mam kolekcję Backbone.js i mam tablicę identyfikatorów modelu, które chcę zapełnić. Wiem, że mogłem pobierać te obiekty jeden po drugim, budować tablicę obiektów i przekazywać je do konstruktora kolekcji jako tablicę.Czy można zainicjować kolekcję kręgosłupa za pomocą identyfikatorów obiektów, a nie obiektów?

Co chcę zrobić, to przekazać tablicę identyfikatorów obiektów do konstruktora jako dane początkowe i pobrać kolekcję, aby pobrać je, prawdopodobnie jako partię, zgodnie z this.

Czy to możliwe?

Odpowiedz

10

Po wywołaniu polecenia "pobierz" w module Backbone.Collection wywoływana jest funkcja Backbone.sync, która domyślnie prosi kolekcję o użycie adresu URL.

Więc jeśli serwer odpowiada:

/models/batch/?ids=1,2,3,4 

Można zrobić coś takiego:

var MyCollection = Backbone.Collection.extend({ 

    model: Model, 

    url: '/models', 

    initialize: function(models, options) { 
     ids = options.ids || []; 
     if (ids.length > 0) { 
      this.fetchByIds(ids); 
     } 
    }, 

    fetchByIds: function(ids) { 
     // Save a reference to the existing url 
     var baseUrl = this.url; 

     // Assign our batch url to the 'url' property and call the server 
     this.url += '/?ids=' + ids.join(','); 
     this.fetch(); 

     // Restore the 'url' property 
     this.url = baseUrl; 
    } 
}); 

i używać go tak:

var coll = new MyCollection({}, {ids: [1, 2, 3, 4]}); 

Trzeba zdać identyfikatory w parametrze options, ponieważ funkcja konstruktora Backbone.Collection ustawia modele przekazane wcześniej w pierwszym parametrze wywołuje funkcję "initialize".

Teoretycznie powinno to zadziałać (czytaj: zupełnie nieuczciwie).

+0

Dziękuję bardzo, dam ci szansę – Joe

3

Można również ustawić adres URL dla funkcji. Właśnie przesłonię pobieranie zamiast fetchByIds: Ponadto, myślę, że baseUrl jest tylko dla modelu, a nie dla kolekcji. Myślę rulfzid ma prawo pomysł, ale myślę, że mogę to zrobić tak:

var MyCollection = Backbone.Collection.extend({ 
    model: Model, 

    initialize: function(models, opts) { 
    if (options.ids) { 
     this.fetch(options.ids); 
    } 
    }, 

    url: function() { 
    var url = ''; 
    if (this.fetch_ids) { 
     // pass ids as you would a multi-select so the server will parse them into 
     // a list for you. if it's rails you'd do: id[]= 
     url = '/models?id=' + ids.join('&id='); 
     // clear out send_ids 
     this.fetch_ids = undefined; 
    } else { 
     url = '/models'; 
    } 
    return url; 
    }, 

    fetch: function(args) { 
    if (args.ids) { 
     this.fetch_ids = args.ids; 
    } 
    return Backbone.Model.prototype.fetch.call(this, args); 
    } 
}); 

myślę, że zachowuje funkcjonalność we właściwym miejscu „”, a to pozwala na większą ponownego wykorzystania (czyli można pobierał (list_of_ids) za każdym razem ... nie trzeba nowy obiekt)

7

w momencie początkowego ładowania strony, nie należy używać sprowadzić - należy bootstrapped jak przy użyciu reset opisaną tutaj: http://documentcloud.github.com/backbone/#FAQ-bootstrap.

Z linkiem:

Ładowanie bootstrapped modele

Kiedy aplikacja pierwszych obciążeń, to często mają komplet modeli początkowych, że wiesz, że będziemy potrzebować, aby uczynić Strona. Zamiast uruchamiać dodatkowe żądanie AJAX, aby je pobrać, ładniejszym wzorcem jest, aby ich dane zostały już załadowane na stronę. Następnie możesz użyć polecenia reset, aby zapełnić swoje kolekcje danymi początkowymi. W DocumentCloud, w szablonie ERB dla obszaru roboczego, robimy coś zgodnie z tymi liniami:

<script> 
    Accounts.reset(<%= @accounts.to_json %>); 
    Projects.reset(<%= @projects.to_json(:collaborators => true) %>); 
</script> 
Powiązane problemy