2013-04-15 157 views
0

這是我的觀點:骨幹查看屬性返回undefined

define(
    [ 
     "jquery" 
    , "underscore"  
    , "backbone" 
    , "eventView" 
    ] 
, function($, _, Backbone, EventView) { 
     "use strict"; 

     var TimelineView = Backbone.View.extend({ 
      tagName: 'div' 
     , className: 'column' 

     , _EventViews: {} // Cache event views for reuse 

     , initialize: function() { 
       this.collection.bind('add', this.add); 
       this.collection.bind('reset', this.add); 
      } 

     , render: function() { 
       return this; 
      } 

      // Listen for additions to collection and draw views 
     , add: function(model) { 
       var eventView = new EventView({ 
        model: model 
       }); 

       // Cache the event 
       console.log(this._EventViews); 
       this._EventViews[model.get('id')] = eventView; 

       // Draw event 
       eventView.render(); 
      } 
     }); 

     return TimelineView 
    } 
); 

正如你可以看到我設置_EventViews屬性包含一個空的對象。但是,當我呼叫add()函數console.log(this._EventViews)返回未定義,並且以下語句失敗。

誰能告訴我這是爲什麼?

回答

2

的問題是內addthis是不是你TimelineView。請參閱本文以獲取javascript中的上下文說明:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this

您可以通過幾種不同的方式解決此問題。在這種情況下最簡單的方法是使用bindon的第三個參數(這兩個參數相同)。

initialize: function() { 
      this.collection.on('add', this.add, this); 
      this.collection.on('reset', this.add, this); 
     } 

或使用listenTo代替。

initialize: function() { 
      this.listenTo(this.collection, 'add', this.add); 
      this.listenTo(this.collection, 'reset', this.add); 
     } 

此外,您_EventViews緩存將通過TimelineView所有實例共享。如果這不是您想要的,請改爲在initialize中創建它。

initialize: function() { 
      this._EventViews = {}; 
      this.listenTo(this.collection, 'add', this.add); 
      this.listenTo(this.collection, 'reset', this.add); 
     } 
+0

只是缺乏對問題的解釋伊莫,但兩點都適用。 – Loamhoof

+0

謝謝,仍然試圖進入Backbone的思維模式,並且每個教程似乎都使用了不同的結構,但我將使用'listenTo'並感謝關於'_EventViews'的靜態頭像。 –

1

它爲我的作品:

<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> 
<script src="http://underscorejs.org/underscore-min.js"></script> 
<script src="http://backbonejs.org/backbone.js"></script> 
<script> 

var TimelineView = Backbone.View.extend({ 
    tagName: 'div' 
, className: 'column' 

, _EventViews: {} // Cache event views for reuse 

, initialize: function() { 
     //this.collection.bind('add', this.add); 
     //this.collection.bind('reset', this.add); 
    } 

, render: function() { 
     return this; 
    } 

    // Listen for additions to collection and draw views 
, add: function(model) { 
     var eventView = ({ 
      model: model 
     }); 

     // Cache the event 
     console.log(this._EventViews); // Prints: Object {} 
     this._EventViews[model.get('id')] = eventView; 

     // Draw event 
     eventView.render(); 
    } 
}); 

var a = new TimelineView(); 
a.add(); 

</script> 

我認爲這個問題是.add()方法是從收集add事件被調用。當您添加監聽器(在骨幹網與.bind()函數來完成),你必須bind(在原生的意思)的功能:

_.bindAll(this, 'add'); 

OR

this.add = this.add.bind(this); 

你必須在你面前做添加函數作爲偵聽器:

initialize: function() { 
    _.bindAll(this, 'add'); 
    this.collection.bind('add', this.add); 
    this.collection.bind('reset', this.add); 
} 
+0

你確定了這個問題,但我完全不同意你的綁定上下文的方法。可以使用版本0.9中引入的'bind'方法(樣板文件)的第三個參數或'listenTo'方法。 – Loamhoof

+0

感謝您的意見,我會永遠優先原生funct.bind(上下文);) –