2012-04-03 77 views
3

以前,我的骨干路由器是这样的:骨干+ Rails的采集获取

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) 

当导航到http://localhost,我会得到index视图渲染,以及对单个元素点击的时候,我会得到show视图渲染。但是,如果我直接访问http://localhost/things/1(即通过输入URL),则不会呈现show视图。我意识到这是因为在@collection.fetch完成之前正在呈现视图。我改变了我的路由器以下内容:

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) 

这工作正常。但是,显然有一点延迟,因为每次切换路由时都会重新获取集合。这是很好的骨干练习吗?不知道是否有更好的方法来做到这一点。

+0

哇,我完全一样的问题。我不认为我会找到正确的词组合来谷歌找到有同样问题的人,但我做到了! – tybro0103 2013-01-03 22:31:18

回答

6

这是jQuery的Deferred()方法的一个很好的用例。

只需创建一个Deferred对象并将其附加到路由器。然后在初始化方法中获取集合,并在Deferred对象上调用resolve()。您的索引和显示方法可以订阅done回调并实例化视图。这个完成的回调将不会运行,直到获取集合。如果它已被提取,那么它立即运行。

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

这很好用!将留下更多的建议,看看会发生什么,但谢谢! – clem 2012-04-03 22:22:34