3

以前、私のバックボーンルーターは次のようになりました。

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://localhostindexビューがレンダリングされ、個々の要素をクリックすると、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)

これは問題なく動作します。ただし、ルートを切り替えるたびにコレクションが再フェッチされるため、明らかに待ち時間が少しあります。これはバックボーンの良い習慣ですか?これを行うためのより良い方法があるかどうかはわかりません。

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 に答える