2012-11-27 13 views
8

Próbuję zrobić podstawowe render() po fetch() na kolekcji (szkieletu 0.9.2):debugowania backbone.js: rendering po pobraniu fetch()

var ProjectListView = Backbone.View.extend({ 
     el: $('#container'), 
     initialize: function() { 
      this.collection = new ProjectsCollection(); 
      this.collection.bind("change", _.bind(this.render, this)); 
      this.collection.fetch({ success: function() { console.log("collection fetched"); } }); 
      ... 
      }, 
     render: function() { 
      console.log("rendered"); 
      ... 

Tworzenie nowych wydruki Zobacz instancji out :

collection fetched

Tak więc render() nigdy nie jest wywoływany po pobraniu(). Co ja tu robię źle? Nie ma wyjątków.

Wszelkie wskazówki dotyczące debugowania tego rodzaju rzeczy w kręgosłupie?

Ps. Wygląda na to, że ta funkcja jest słabo udokumentowana, biorąc pod uwagę liczbę pytań na temat SO.

Odpowiedz

28

Z fine manual:

sprowadzićcollection.fetch([options])

Fetch domyślny zestaw modeli dla tej kolekcji z serwera, resetujący kolekcję po jej otrzymaniu. [...] Gdy dane modelu powrócą z serwera, kolekcja zostanie zresetowana.

Co robi reset? reset robi to:

zresetowaćcollection.reset(models, [options])

[...] Użyj zresetować zastąpić kolekcję z nową listą modeli (lub skrótów atrybut), wywołując jeden "reset" imprezę u koniec.

Więc fetch wzywa reset zaktualizować modele kolekcji i reset wyzwala "reset" razie nie zdarzenie "change". Żaden z modeli się nie zmienił, a wydarzenia kolekcji "change" pochodzą z jego modeli.

Powinieneś render związany "reset":

initialize: function() { 
    this.collection = new ProjectsCollection(); 
    this.collection.bind("reset", _.bind(this.render, this)); 
    this.collection.fetch(...); 
} 

Jeśli chcesz słuchać "change" wydarzeń dotyczących zawartych modeli następnie można powiązać "change" obsługi do kolekcji since:

You można powiązać zdarzenia "change", aby otrzymać powiadomienie o zmodyfikowaniu dowolnego modelu w kolekcji,
[...]
Każde zdarzenie wyzwalane w modelu w kolekcji będzie również wyzwalane bezpośrednio w kolekcji dla wygody.

Kolekcja będzie również generować zdarzenia "add" i "remove" w miarę zmian samej kolekcji.


Nowsze wersje Backbone nie dłuższe zbiory RESET podczas fetch:

Kiedy powraca model danych z serwera, używa ustawić do (inteligentnie) scalić pobranych modeli, chyba że przejdzie {reset: true}, w takim przypadku kolekcja będzie (efektywnie) zresetować.

I set:

[...] wykonuje "inteligentny" aktualizację kolekcji z przekazanym liście modeli. Jeśli model z listy nie znajduje się jeszcze w kolekcji, zostanie dodany; jeśli model jest już w kolekcji, jego atrybuty zostaną scalone; a jeśli kolekcja zawiera jakiekolwiek modele, których nie ma na liście, zostaną one usunięte. Wszystkich odpowiednich "add", "remove" i "change" wydarzeń są wypalane jak to się dzieje

Więc z nowszymi wersjami Backbone będziemy chcieli wymienić na "add", "remove" i "change" wydarzenia (które rzutem kolekcja oparta powinna słuchajcie mimo to); możesz także użyć {reset: true} na początkowej fetch i wysłuchać również "reset". Polecam następujące podejście oparte na widokach zbiórki:

  1. Słuchaj "add" i obsługi tego zdarzenia z zwrotnego, które po prostu dodaje jeden element do widzenia, nie rzucać wszystko z dala i ponownego renderowania.
  2. Posłuchaj "remvoe" i obsłużyć to zdarzenie za pomocą wywołania zwrotnego, które usuwa tylko nowo usunięty model.
  3. Słuchaj "change" i postępuj tak, używając wywołania zwrotnego, które zastępuje (lub aktualizuje) odpowiedni element.
  4. Posłuchaj "reset" i połącz z render. Następnie prześlij {reset: true} do początkowego wywołania kolekcji fetch.

To zatrzyma ważne wydarzenia, a widok kolekcji wykona minimalną ilość pracy, aby poradzić sobie z każdym z nich. Oczywiście ta strategia nie ma zastosowania do wszystkich sytuacji, ale uważam, że jest to dobry punkt wyjścia.

+0

Dziękuję za dokładną odpowiedź, mam nadzieję, że będzie to przydatne dla innych. PS. Czy istnieją inne zasoby, które możesz polecić poza oficjalnymi dokumentami? – Fdr

+0

@Fdr: Przeczytałem dokumenty i kod źródłowy w celach informacyjnych. Po ponad 15 latach wszystkie struktury wyglądają prawie tak samo. –

+0

Chyba tak.Te zdarzenia w szkielecie są potknięciami bitów: "reset" jest podnoszony dla kolekcji, ale nie ma podobieństwa podczas wykonywania model.fetch() (co powoduje, że "zmiana" jest emitowana). Słaby projekt api? – Fdr

3

Ok, więc dopóki ktoś może wyjaśnić dlaczego wiązania nie działa, użyłem następujące rozwiązania:

initialize: function() { 
      var self = this; 
      this.collection = new ProjectsCollection(); 
      this.collection.fetch({ success: function() { self.render(); } }); 

Powiązane problemy