2

我正在尝试实现一些看起来对 Backbone 来说应该相对微不足道的东西,但它不起作用。我正在根据用户的操作用系列填充图表。代码如下。

假设用户快速添加了两个系列。或者一条路线同时触发两个系列。常量是在第一个返回之前触发第二次获取。在这种情况下,“fetching”被记录了两次,而“fetched”只被记录了一次。这是预期的行为,如果不是,我应该如何构建我的代码以使其工作?

# Series model
class Series extends Backbone.Model
    initialize: (options) ->
        _.bindAll @
        @endpoint = state?.getEndpoint()

    url: ->
        [localApiUrl, 'metrics', @endpoint, @.get('id')].join('/')



class SeriesCollection extends Backbone.Collection
    model: Series,

    initialize: ->
        _.bindAll @
        @bind 'add', @fetched

    fetchData: ( opts ) =>
        console.log('fetching')
        @series = new Series({ id: opts.id })
        @series.fetch
            success: (model, response) =>
                @.add({
                    id: @series.get('id')
                    name: @series.get('id')
                    data : @series.get('ts')
                    marker:
                        radius: 2
                    turboThreshold: 10000 
                    dataGrouping: 
                        enabled: false
                })

    fetched: () ->
        console.log('fetched', @)
4

1 回答 1

4

将重复模型添加到集合中没有任何作用;特别是,它不会触发"add"事件,因为不会添加任何内容。考虑一下:

# c is an empty collection
c.add(id: 1, t: 'where is')
c.add(id: 2, t: 'pancakes house?')
c.add(id: 1, t: 'different')

这将生成两个事件,并且"add"集合最终将作为模型,第三个将被忽略。(1, 'where is')(2, 'pancakes house?')add

演示:http: //jsfiddle.net/ambiguous/WUH6f/

0.9.2 更新日志有这样的说法:

  • 在将重复模型添加到集合时不会引发错误,Backbone 现在会静默地跳过它们。

因此,如果fetchData被调用两次,您将收到两次调用console.log('fetching'). 但是,如果opts.id对 的两个调用都相同fetchData,那么第二个@add将被忽略,因为id == opts.id集合中已经有一个模型。


你说opts.id每次都不一样,但这并不一定意味着@series.get('id')会有所不同。请记住,AJAX 中的A代表异步因此您可能会看到与此类似的一系列事件:

  1. 有东西在呼唤fetchData(id: 1)@series.id现在将是 1。
  2. 进行 AJAX 调用。
  3. 有东西在呼唤fetchData(id: 2)@series.id现在将是 2。请记住,这@series是一个实例变量,而不是局部变量。
  4. 服务器从第一个 AJAX 调用返回并success触发处理程序。@series.id现在是 2,将添加Seriesfrom 3 。
  5. 服务器从第二个 AJAX 调用返回并触发成功处理程序。@series.id仍然是 2,所以Seriesfrom 3将再次添加。但是这个将是重复的,所以add会忽略你。

您应该能够通过对相关系列使用普通的旧局部变量而不是实例变量来解决此问题:

fetchData: ( opts ) =>
    console.log('fetching')
    series = new Series({ id: opts.id })
    series.fetch
        success: (model, response) =>
            @add(
                id: series.get('id')
                #...
            )

你不需要里面.@.add所以我把它拿出来了。我还在@add通话中放下了大括号,因为您也不需要它们;你也可以去掉括号,但我把它们留在里面,因为我发现它们有助于澄清代码的块结构。

我应该首先发现这个问题,对不起。

于 2012-06-14T04:35:36.407 回答