Привязка к событию изменения модели не работает в представлении в backbone.js - PullRequest
3 голосов
/ 28 февраля 2012

Я создаю очень простое базовое приложение для ознакомления с фреймворком.Все работает, кроме привязки событий изменения модели к функции на мой взгляд.Я проверил предыдущие вопросы по SO, и ни один из них не помог.

В моей модели есть одна переменная 'counter'.Вид имеет 2 кнопки, которые увеличивают или уменьшают «счетчик» модели.Простые вещиЭто все работает нормально, но когда я пытаюсь прослушать события изменения модели в представлении, я получаю уведомление только один раз - при создании модели (я полагаю, что при создании значений по умолчанию).

Я знаю, что счетчик обновляется, потому что, если я вручную вызываю рендер после обновления модели, я вижу эффект, но в интересах лучшей структуры mvc-ish, я хочу просмотреть, чтобы получать уведомления о событиях измененияи обновить себя.

Ниже приведен код кофейного кода.

  $ ->

      class Count extends Backbone.Model

           defaults: counter : 0

           change: -> console.log('changed')


      class Spinner extends Backbone.View

           el: $('#counterView')

           initialize: =>

                @model = new Count()
                @model.bind 'change' , @update()

           events:
                'click button#incBtn' : 'inc'
                'click button#decBtn' : 'dec'

           inc: ->

                @model.set counter : @model.get('counter') + 1

           dec: ->

                @model.set counter : @model.get('counter') - 1

           update: ->

                console.log('update')
                $('#num').html(@model.get 'counter')

      view = new Spinner()

HTML:

<body>
    <div id="counterView">
        <button id="incBtn">Increment</button>
        <button id="decBtn">Decrement</button>
    <div id="num">Number</div>
    </div>    
</body>

Заранее спасибо.б

Ответы [ 2 ]

5 голосов
/ 28 февраля 2012

Ваша ошибка здесь:

@model.bind 'change' , @update()

То, что вы говорите, это связывание события change с тем, что @update() возвращает , когда вы хотите связать его с @update самой . Так и должно быть:

@model.bind 'change' , @update

(без скобок). Как бы то ни было, Spinner.update будет немедленно выполняться на Spinner.initialize, в точности, как вы узнали. Еще несколько заметок:

  • Нет необходимости ждать document.ready для создания ваших классов. Сначала вы можете сделать это (за пределами document.ready) и создавать экземпляры моделей, видов и т. Д. Только на document.ready.
  • Кажется странным создание новой модели внутри вашего взгляда. Вы, вероятно, хотите сделать что-то вроде этого:

    view = new Spinner(model: new Count)
    

Редактировать: Как Тревор Бернхэм отмечает ниже , вам нужна жирная стрелка => на inc, dec и update. Исправлено ниже.

Взятые вместе:

class Count extends Backbone.Model

     defaults: counter : 0

     change: -> console.log('changed')


class Spinner extends Backbone.View

     el: '#counterView'

     initialize: =>

          @model.bind 'change' , @update

     events:
          'click button#incBtn' : 'inc'
          'click button#decBtn' : 'dec'

     inc: =>

          @model.set counter : @model.get('counter') + 1

     dec: =>

          @model.set counter : @model.get('counter') - 1

     update: =>

          console.log('update')
          @$el.find('#num').html(@model.get 'counter')

 $ ->
     view = new Spinner(model: new Count)
2 голосов
/ 29 февраля 2012

Хорошо, так что после некоторого возни, работает следующее.По какой-то причине при обновлении модели не удается отправить событие обратно в представление, поэтому я вручную отправляю событие изменения из модели с помощью:

 @trigger('change')

Довольно неуклюже, но это единственноевещь, которая работает для меня.

Я также заметил странное поведение при использовании значений по умолчанию, поэтому теперь я устанавливаю счетчик с инициализацией (а не через значения по умолчанию).Чтобы увидеть непреднамеренное поведение со значениями по умолчанию, раскомментируйте значения по умолчанию и закомментируйте инициализацию.Это как событие изменения не отправляется всякий раз, когда счетчик = исходное значение 0.

class Count extends Backbone.Model

      #defaults: counter : 0

      initialize: ->
           @set counter : 0

      change: ->
           @trigger('change') #this lil fella made it work

 $ ->
      class Spinner extends Backbone.View

           el: $('#counterView')

           initialize: =>
                @model = new Count
                @model.bind 'change' , @update
                @update()

           events:
                'click button#incBtn' : 'inc'
                'click button#decBtn' : 'dec'

           inc: =>
                @model.set counter : @model.get('counter') + 1

           dec: =>                    
                @model.set counter : @model.get('counter') - 1

           update: =>                    
                $('#num').html(@model.get 'counter')


           view = new Spinner()
...