2012-02-28 111 views
3

我正在創建一個非常簡單的骨幹應用程序來熟悉框架。除了將模型更改事件綁定到我認爲的函數外,所有工作都正在進行。我檢查了以前的SO問題,但都沒有幫助。綁定到模型更改事件不能在backbone.js中查看

我的模型有一個變量'counter'。 View有兩個按鈕,可以增加或減少模型的「計數器」。簡單的東西。這一切都工作正常,但是當我嘗試在視圖中偵聽模型更改事件時,我僅在創建模型時(我創建默認值時纔會收到一次通知)。

我知道計數器正在更新,因爲如果我在更新模型後手動調用渲染,我可以看到效果,但爲了更好地使用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> 

在此先感謝。 b

回答

5

你的錯誤是在這裏:

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

編輯:作爲Trevor Burnham notes below,你想在incdecupdate脂肪箭頭=>。下面修正。

綜上所述:

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) 
+0

感謝您對Linus的反饋。不幸的是,它沒有解決問題。該視圖仍未被通知模型更改。模型正在更新,並且更改事件像以前一樣被調度,但視圖的更新函數從未聽說過它。 – 2012-02-28 19:15:03

+1

你確定'console.log('update')'不能運行?在這之後,我看到一個問題:'@ model.get'counter''不起作用,因爲'@ update'的上下文在將它傳遞給'@ model.bind'時會丟失。輕鬆修復:用胖箭頭定義'update'('=>')。 – 2012-02-28 19:20:20

+0

感謝@TrevorBurnham,上面已更新。 – 2012-02-28 23:17:38

2

好了,一些擺弄之後,正在以下。出於某種原因,當模型更新,它無法調度事件回視,所以我手動從模型調度change事件有:

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