0

这是我的看法:

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 并且以下语句失败。

谁能告诉我这是为什么?

4

2 回答 2

2

问题是,在addthis不是您的 TimelineView。有关 javascript 上下文的说明,请参阅本文:https ://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this

您可以通过几种不同的方式解决此问题。这种情况下最简单的就是使用bindor的第三个参数on(这两个是一样的)。

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);
        }
于 2013-04-15T16:17:04.093 回答
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');

或者

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

在将函数添加为侦听器之前,您必须这样做:

initialize: function() {
    _.bindAll(this, 'add');
    this.collection.bind('add', this.add);
    this.collection.bind('reset', this.add);
}
于 2013-04-15T16:12:47.947 回答