绑定到在backbone.js中不在视图中工作的模型更改事件

时间:2012-02-28 13:39:43

标签: events backbone.js coffeescript

我正在创建一个非常简单的骨干应用程序来熟悉框架。除了将模型更改事件绑定到我视图中的函数之外,所有工作都正常。我已经检查了以前关于SO的问题,没有人帮助过。

我的模型有一个变量'counter'。 View有2个按钮,可以增加或减少模型的“计数器”。简单的东西。这一切都很好,但是当我尝试在视图中监听模型更改事件时,我只会在模型创建时收到通知(创建默认值时,我会假设)。

我知道计数器正在更新,因为如果我在更新模型后手动调用渲染我可以看到效果,但为了更好的mvc-ish结构,我想查看更改事件和更新的通知本身。

以下是coffeescript代码。

  $ ->

      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>

提前致谢。 B'/ P>

2 个答案:

答案 0 :(得分:5)

您的错误在这里:

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

当您要将change 绑定到@update() 时,将@update事件与<{1}} 返回绑定}本身。所以它应该是:

@model.bind 'change' , @update

(没有括号)。事实上,Spinner.update会立即在Spinner.initialize上执行,就像您发现的那样。还有一些注意事项:

  • 没有必要等待document.ready创建您的课程。您可以先执行此操作(在document.ready之外),并仅在document.ready上实例化模型,视图等。
  • 在视图的中创建新模型似乎有点奇怪。你可能想做这样的事情:

    view = new Spinner(model: new Count)
    

修改:在Trevor Burnham notes below,您需要=>incdec上的粗箭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)

答案 1 :(得分:2)

好的,经过一番摆弄,以下是有效的。出于某种原因,当模型更新时,它无法将事件调度回视图,因此我手动从模型中调度更改事件:

 @trigger('change')

非常笨重,但它是唯一对我有用的东西。

我在使用默认值时也注意到了古怪的行为,所以我现在用初始化(而不是默认值)来设置计数器。要使用默认值查看意外行为,请取消注释默认值并注释掉初始化。这就像每当counter =原始值为0时都不会调度change事件。

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()