2012-04-03 10 views
3
holen

Zuvor sah mein Backbone-Router wie folgt aus:Backbone + Rails Sammlung

class App.Routers.ThingsRouter extends Backbone.Router 
    routes: '': 'index' 
    routes: 'previews/:id': 'show' 

    initialize: -> 
    @collection = new App.Collections.ThingsCollection 
    @collection.fetch 

    index: -> 
    view = new App.Views.ThingsIndex(collection: @collection) 
    $('#app-container').html(view.render().el) 

    show: (id) -> 
    @model = @collection.get(id) 
    view = new App.Views.ThingsShow(model: @model) 
    $('#app-container').html(view.render().el) 

Wann http://localhost Navigation, würde ich die index Ansicht gerendert bekommen, und wenn sie auf einzelne Elemente klicken, würde ich die show Ansichten gerendert Wenn ich jedoch direkt zu http://localhost/things/1 ging (d. H. Durch Eingabe der URL), würde die show Ansicht nicht gerendert werden. Ich erkannte, dass dies daran lag, dass die Ansicht gerendert wurde, bevor @collection.fetch fertiggestellt wurde. Ich änderte meinen Router zu den folgenden:

class App.Routers.ThingsRouter extends Backbone.Router 
    routes: '': 'index' 
    routes: 'previews/:id': 'show' 

    initialize: -> 
    @collection = new App.Collections.ThingsCollection 

    index: -> 
    @collection.fetch success: => 
     view = new App.Views.ThingsIndex(collection: @collection) 
     $('#app-container').html(view.render().el) 

    show: (id) -> 
    @collection.fetch success: => 
     that.model = that.collection.get(id) 
     view = new App.Views.ThingsShow(model: @model) 
     $('#app-container').html(view.render().el) 

Das funktioniert gut. Es gibt jedoch offensichtlich eine kleine Latenzzeit, da die Sammlung jedes Mal neu geladen wird, wenn ich Routen umschalte. Ist das ein gutes Backbone-Training? Nicht sicher, ob es einen besseren Weg gibt, dies zu tun.

+0

Wow, meine genaue Frage. Ich dachte nicht, dass ich die richtige Kombination von Wörtern finden würde, um zu googeln, um jemanden mit dem gleichen Problem zu finden, aber ich tat es! – tybro0103

Antwort

6

Dies ist ein großer Anwendungsfall für die Deferred() Methode von jQuery.

Erstellen Sie einfach ein verzögertes Objekt und hängen Sie es an den Router an. Rufen Sie dann die Auflistung in der Initialisierungsmethode ab, und rufen Sie resolve() für das verzögerte Objekt auf. Ihre Index- und show-Methoden können den Rückruf done abonnieren und die Ansicht instanziieren. Dieser Rückruf wird nicht ausgeführt, bis die Sammlung abgerufen wurde. Und wenn es schon geholt wurde, dann läuft es sofort.

class App.Routers.ThingsRouter extends Backbone.Router 
    routes: '': 'index' 
    routes: 'previews/:id': 'show' 

    initialize: -> 
    @collectionFetched = new $.Deferred 
    @collection = new App.Collections.ThingsCollection 
    @collection.fetch success: -> 
     @collectionFetched.resolve() 

    index: -> 
    that = this 
    @collectionFetched.done -> 
     view = new App.Views.ThingsIndex(collection: that.collection) 
     $('#app-container').html(view.render().el) 

    show: (id) -> 
    that = this 
    @collectionFetched.done -> 
     that.model = that.collection.get(id) 
     view = new App.Views.ThingsShow(model: that.model) 
     $('#app-container').html(view.render().el) 
+0

Das funktioniert super! Will für weitere Vorschläge herumhängen, um zu sehen, was passiert, aber danke! – clem

Verwandte Themen