注册事件处理程序的基本主干问题

时间:2015-09-16 22:01:16

标签: javascript jquery dom backbone.js

我真的不明白Backbone应该如何处理在HTML插入DOM之前在HTML上注册事件处理程序的常见场景。

大多数Backbone视图都是这样的:

var PortalView = Backbone.View.extend({


        events: {

            'click #logout-li-id': 'onClickLogout'   //1 (doesn't work)
        },

        initialize: function (opts) {


            var self = this;

            $('#logout-li-id').on('click', function (event) { //2 (doesn't work because '#logout-li-id' is not in the DOM yet
               event.preventDefault();
               alert(event);
            });

        },

        render: function () {

            var self = this;

            var template = allTemplates['templates/portalTemplate.ejs'];

            var ret = EJS.render(template, {});

            $('#main-div-id').html(ret);

            $('#logout-li-id').on('click', function (event) { //3 works!
                event.preventDefault();
               alert(event);
            });

            return this;

        },
        onClickLogout: function(event){
           alert(event);
         }
    });

正如您在上面所看到的,我已经标记了3个类似的调用来在DOM元素'#logout-li-id'上注册事件处理程序 - 问题是在DOM元素上注册回调的唯一成功调用在渲染函数(调用#3)中,之后出现,这个Backbone视图被插入到DOM中。因此,在Backbone视图的事件对象中声明键的标准方法不起作用!那么用Backbone做这件事的正确方法是什么?

1 个答案:

答案 0 :(得分:3)

Backbone期望视图将通过events哈希处理的事件是视图el的子节点(即视图的根DOM元素)。看起来你可能没有将这个视图附加到你正在听的DOM元素的父元素 - $('#main-div-id')是视图的el的孩子吗?

这里的标准方法是:

var PortalView = Backbone.View.extend({

    // Associate this view with the element it will manage
    el: '#main-div-id',

    events: {
        'click #logout-li-id': 'onClickLogout'
    },

    render: function () {
        var template = allTemplates['templates/portalTemplate.ejs'];
        var ret = EJS.render(template, {});
        // Render to this view's element
        this.$el.html(ret);
    }
});

更多详细信息:events哈希通过将委派的事件处理程序添加到视图的DOM节点来工作。实质上,视图的DOM树中的每次单击都将调用一个处理程序,该处理程序检查事件目标是否与给定的选择器匹配。如果是这样,它会将事件传递给您指定的view方法。但这只有在您单击的元素位于视图的DOM树中时才有效 - 否则,视图的DOM将永远不会获取事件,并且永远不会调用事件处理程序。