Backbone View属性返回undefined

时间:2013-04-15 16:01:35

标签: javascript backbone.js

以下是我的观点:

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)时,返回undefined并且以下语句失败。

谁能告诉我为什么会这样?

2 个答案:

答案 0 :(得分:2)

问题是在add内,this不是您的时间线视图。有关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); } 中创建。

{{1}}

答案 1 :(得分: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);
}