将 this.el 与主干.js子视图混淆

Confusing this.el in backbone.js with subviews

本文关键字:视图 js this el      更新时间:2023-09-26

我在主干网的子视图方面有一个大问题.js。我有两个视图,我想将第二个视图呈现为第一个视图的元素。所以我在第二个视图中定义了this.el,该视图引用了第一个视图中的部分(section#user-data(。

我在渲染第一个视图后创建第二个视图的对象,如果我写 alert($('#user-data').length)在我创建对象之前,我得到一个 1,所以它存在。

但是在第二个视图中,我得到了一个未定义的视图。如果我以任何方法登录this.el。但是,如果我使用例如身体进行this.el则一切都按预期工作。

这是什么原因呢?

例:

   /**
     * The example of a view for profile's component
     *
     *
     * @module Profile
     * @submodule Frontend
     * @class ProfileView
     * @constructor
     *
     */
    ProfileView = Backbone.View.extend({
        // The tagname wrapping the rendered content
        // The template for the current view
        template : _.template('COMPONENTS_VIEW_FRAME'),
        /**
         * The initialisation for the current view (kind of constructor)
         *
         * @method initialize
         */
        initialize : function() {
        },
        /**
         * The rendering process for the current view
         *
         * @method render
         * @param {String} oLocas the data to render inside this view
         */
        render : function(oLocas) {
            $(this.el).html(this.template(oLocas));
            return this;
        }
    });
           /**
     * The example of a view for profile's component
     *
     *
     * @module Profile
     * @submodule Frontend
     * @class ProfileView
     * @constructor
     *
     */
    ProfileSectionView = Backbone.View.extend({
        // The tagname wrapping the rendered content
        // The template for the current view
        template : _.template('COMPONENTS_VIEW_OPTION_SECTION'),
        el : $('#user-data'),
        events : {
            'click a.open_close_section' : 'doIt'
        },
        headline : 'ddd',
        /**
         * The initialisation for the current view (kind of constructor)
         *
         * @method initialize
         */
        initialize : function() {
            alert($(this.el).length);
        },
        doIt : function(event) {
            alert('jo');
        },
/**
         * The rendering process for the current view
         *
         * @method render
         * @param {String} eventName the name of the triggered event
         */
        render : function(oLocas) {
            $(this.el).html(this.template(oLocas));
            return this;
        }
    });
            // Here I start to use the first view
            var oProfileView = new ProfileView();
                $('#profile').html(oProfileView.render().el).fadeIn(500,    function() {
                    $(this).removeClass('closed');
                                            // Here I create the second view
                    var oProfileSectionView = new ProfileSectionView({
                        model : this.model
                    });
                    oProfileSectionView.render({
                        headline : 'XXX',
                        sectionrows : 'ddd'
                    }).el;
                });
这是

JavaScript的一个小问题。

JavaScript 在定义 ProfileSelectionView 时会寻找该元素。所以这个:

ProfileSectionView = Backbone.View.extend({
    // ...
    el : $('#user-data'),
    // ...
});

实际上正在ProfileSelectionView的定义中进行评估,而不是稍后当您实例化ProfileSelectionView实例时。

要解决此问题,请将el的定义移动到初始化中:

ProfileSectionView = Backbone.View.extend({
    // ...
    // Do not define the el here. I've commented it out
    // el : $('#user-data'),
    // ...
    initialize : function() {
        this.setElement($('#user-data'));
    },
    // ...
});

或者更好的是,您可以在创建ProfileSelectionView时传递元素(如 Backbone.js 文档中所述(:

var oProfileView = new ProfileView();
$('#profile').html(oProfileView.render().el).fadeIn(500,    function() {
    // ...
    var oProfileSectionView = new ProfileSectionView({
        model : this.model,
        el: $('#user-data')
    });
    // ...
});

通过这样做,您不必在 ProfileSelectionView 中定义initialize函数。