2013-04-15 96 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(上下文);) –