3

以前,我的 Backbone 路由器是这样的:

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)

哪个工作正常。但是,由于每次切换路由时都会重新获取集合,因此显然会有一点延迟。这是很好的 Backbone 做法吗?不确定是否有更好的方法来做到这一点。

4

1 回答 1

6

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

只需创建一个 Deferred 对象并将其附加到路由器。然后在 initialize 方法中获取集合并调用resolve()Deferred 对象。您的 index 和 show 方法可以订阅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)
于 2012-04-03T22:04:45.223 回答