如何在Backbone.js中避免使用循环引用的Stack Overflow?

时间:2012-03-29 06:28:38

标签: callback backbone.js stack-overflow infinite-loop silent

我的模型中的两个属性应该在更改后相互更新一次。 startDateendDate。它们的值是来自moment.js库的Moment对象。

具有相同日期的两个Moment对象不等效,因此这会导致超过最大堆栈的循环,因为它们看起来总是在Backbone中发生变化。

new moment('01/01/12') == new moment('01/01/12') // => false

{ silent: true }选项似乎没有帮助,我认为因为它only defers the change event而不是完全压制它,尽管我不确定。

以下是溢出的代码:

class Paydirt.Models.BlockBrowser extends Backbone.Model
  initialize: =>
    @on('change:startDate', @updateEndDate)
    @on('change:endDate', @updateStartDate)

  updateStartDate: =>
    @set({ startDate: @cloneEndDate().subtract('days', @get('interval')) }, { silent: true }         

  updateEndDate: =>
    @set({ endDate: @cloneStartDate().add('days', @get('interval')) }, { silent: true } ) 

  cloneStartDate: => new moment(@get('startDate'))
  cloneEndDate: => new moment(@get('endDate'))

我可以设置一个全局标志来阻止回调循环,如下所示:

  updateStartDate: =>
    if !@changing
      @changing = true
      @set({ startDate: @cloneEndDate().subtract('days', @get('interval')) }, { silent: true } ) 
      @changing = false

  updateEndDate: =>
    if !@changing
      @changing = true
      @set({ endDate: @cloneStartDate().add('days', @get('interval')) }, { silent: true } ) 
      @changing = false

......但这显然是一个令人讨厌的解决方案。在这个用例中我有更好的模式吗?

谢谢。

3 个答案:

答案 0 :(得分:1)

另一个想法:

您使用的是Backbone v0.9.2 吗?看起来它正在更加密集地使用options.silentLook here

您描述的options.silent行为看起来更像v0.9.1。

答案 1 :(得分:0)

两个想法:

  1. 覆盖Underscore方法_.isEqual以正确管理您的Moment个对象。您可以使用Proxy pattern

  2. 使用custom events可以更好地控制它们被触发。

答案 2 :(得分:0)

我不确定如何在骨干网中执行此操作,但您可以比较时刻的整数值

(moment().valueOf() === moment().valueOf()) // true

(+moment() === +moment) // true