如何在从collection.parse覆盖调用时返回model.fetch()后更新CompositeView?

时间:2012-08-27 03:53:28

标签: javascript backbone.js coffeescript marionette

示例:http://franklovecchio-playback.herokuapp.com/?log=true

完整代码:https://github.com/franklovecchio/playback

在我在解析覆盖上返回模型后,您会看到错误:Uncaught TypeError: Object #<Thing> has no method 'serializeData'上出现“未定义”属性。

最初,我将Collection绑定到CompositeView:

things = new App.Collections.Things()
things.fetch()

# Render
App.Pages.State.Action1.getLayout().content.show new App.CompositeViews.Action1Things(
  collection: things
)

在集合parse方法中,我fetch有关模型的更多详细信息(返回名为extra的属性,该属性呈现为未定义:

class App.Collections.Things extends Backbone.Collection

  url: '/things'
  model: App.Models.Thing

  @trace initialize: () ->

  # Override response to get more detailed information about thing.
  @trace parse: (resp) ->

    things = []

    _.each resp, (item) =>

      # Fetch detailed information about thing
      thing = new App.Models.Thing(
        id: item.id
        name: item.name
      )

      thing.fetch()

      things.push thing

    things

然后,在模型中:

class App.Models.Thing extends Backbone.Model

  defaults:
    name: 'n/a'
    extra: 'n/a'

  urlRoot: () ->
    '/thing'

  defaults:
    name: null

  @trace initialize: () ->

    @name = @attributes.name
    @extra = @attributes.extra

  @trace parse: (resp) -> 

    debug.info 'resp: ' + JSON.stringify resp

    @id = resp.id
    @attributes.id = @id

    @name = resp.name
    @attributes.name = @name

    @extra = resp.extra
    @attributes.extra = @extra

    @

评论:

@extra = resp.extra
@attributes.extra = @extra

导致错误消失,但CompositeView甚至没有尝试更新。如何使用获取的模型响应使CompositeView在parse()完成时更新?

(虽然示例没有显示,但我必须覆盖,因为响应不像Backbone想要的那样返回,以防你想知道)。

3 个答案:

答案 0 :(得分:1)

使用jQuery deferred对象推迟视图的呈现,直到收集请求完成:

things = new App.Collections.Things()
things.deferred = things.fetch()

things.deferred.done(function() {
  App.Pages.State.Action1.getLayout().content.show new App.CompositeViews.Action1Things(
    collection: things
  )
});

更多信息:Backbone.js calling render after collection is populated

答案 1 :(得分:0)

我必须修改ItemView和CompositeView的on 'change'事件:

ItemView

class App.ItemViews.Action1Thing extends Backbone.Marionette.ItemView
  template: '#template-action1-thing'
  @trace initialize: (options) ->

    @model.on 'change', @render

ItemView

class App.ItemViews.Action1Thing extends Backbone.Marionette.ItemView
  template: '#template-action1-thing'
  @trace initialize: (options) ->

    @model.on 'change', () ->
      @render

CompositeView

class App.CompositeViews.Action1Things extends Backbone.Marionette.CompositeView

  template: '#template-action1-things'
  collectionEl: 'tbody#things_collection'
  itemView: App.ItemViews.Action1Thing

  @trace initialize: (options) ->

    @collection.on 'change', @render

CompositeView new

class App.CompositeViews.Action1Things extends Backbone.Marionette.CompositeView

  template: '#template-action1-things'
  collectionEl: 'tbody#things_collection'
  itemView: App.ItemViews.Action1Thing

  @trace initialize: (options) ->

    @collection.on 'change', (model) ->
      @.remove model
      @.add model
      @render

答案 2 :(得分:-3)

以下应该绝对有用,它对我有用......

而不是下面的

this.collection.fetch();

使用此

this.collection.fetch(async: false);