0

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

两个相同日期的 Moment 对象是不等价的,因此这会导致一个超出最大堆栈的循环,因为它们在 Backbone 看来总是改变。

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

我认为该{ silent: true }选项似乎无济于事,因为它只是推迟更改事件,而不是完全抑制它,尽管我不确定。

这是溢出的代码:

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

......但这显然是一个hacky的解决方案。在这个用例中是否有更好的模式可供我遵循?

谢谢你。

4

3 回答 3

1

另一个想法:

您使用的是 Backbone v0.9.2吗?看起来它正在更密集地使用options.silent. 看这里

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

于 2012-03-29T08:31:35.833 回答
0

两个想法:

  1. 覆盖 Underscore 方法_.isEqual以正确管理您的Moment对象。您可以使用代理模式

  2. 使用自定义事件可以在触发它们时获得更多控制。

于 2012-03-29T08:21:02.053 回答
0

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

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

或者

(+moment() === +moment) // true
于 2012-04-24T01:01:00.293 回答