Как избежать переполнения стека с помощью циклических ссылок в Backbone.js? - PullRequest
0 голосов
/ 29 марта 2012

Два атрибута в моей модели должны обновлять друг друга при изменении, один раз. startDate и endDate. Их значения - это объекты 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

... но это, очевидно, хакерское решение. Есть ли лучший пример для меня, чтобы следовать в этом случае использования?

Спасибо.

Ответы [ 3 ]

1 голос
/ 29 марта 2012

Другая идея:

Используете ли вы Backbone v0.9.2 ? похоже, что он более интенсивно использует options.silent. Смотрите здесь .

Поведение options.silent, которое вы описываете, больше похоже на v0.9.1.

0 голосов
/ 24 апреля 2012

Я не уверен, как это сделать в магистрали, но вы можете сравнить целочисленное значение моментов

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

или

(+moment() === +moment) // true
0 голосов
/ 29 марта 2012

Две идеи:

  1. Перезаписать метод Underscore _.isEqual, чтобы правильно управлять объектами Moment.Вы можете использовать шаблон Proxy .

  2. . Использовать пользовательских событий , чтобы иметь больший контроль, чем при их запуске.

...