Backbone.js 主干单击事件未在模板视图中触发

Backbone.js 主干单击事件未在模板视图中触发,backbone.js,backbone-views,backbone-events,Backbone.js,Backbone Views,Backbone Events,我正在开发一个基于动态模板的主干应用程序。我有一个页眉视图、侧面板视图和页脚视图,它们在调用任何其他视图时都会动态初始化。 问题是每个模板视图上都有未触发的事件。例如,我有一个按钮可以更改header视图中的语言,但它的事件没有触发 我的标题视图: define([ "jquery", "backbone", "text!../../pages/header.html" ], function($, Backbone, headerTpl) { var header =

我正在开发一个基于动态模板的主干应用程序。我有一个页眉视图、侧面板视图和页脚视图,它们在调用任何其他视图时都会动态初始化。 问题是每个模板视图上都有未触发的事件。例如,我有一个按钮可以更改header视图中的语言,但它的事件没有触发

我的标题视图:

define([ "jquery", "backbone", "text!../../pages/header.html" ], function($,
        Backbone, headerTpl) {

    var header = Backbone.View.extend({
        events : {
            "click #enBtn":"swichToEnglish",
             "click #frBtn":"swichToFrench"
        },
        initialize : function(options) {
             _.bindAll(this, "swichToFrench","swichToEnglish");

            this.render(options.parent);
            //$("#enBtn").css("pointer-events","none");

        },
        render : function(parent) {
            this.template = _.template(headerTpl);
            $(parent).append(this.template);
            return this;
        },
        swichToFrench:function(){
            console.log("switch to frensh");
            if(i18n.currentLocal == 'en'){
                i18n.currentLocal='fr';
                $("#frBtn").css("pointer-events","auto");
                this.render(options.parent);
        }
        },
        swichToEnglish:function(){
            console.log("switch to English");
            if(i18n.currentLocal == 'fr'){
                i18n.currentLocal='en';
                $("#enBtn").css("pointer-events","auto");
                $("#frBtn").css("pointer-events","none");
                this.render(options.parent);
        }   
        }
    });

    return header;
});
在路由器中调用标头视图:

self._header = new Header({parent: $(".main_container")});

有没有办法解决这个问题。我需要知道如何触发这些事件,谢谢。

事件处理程序不触发的原因是事件处理程序被委托给views元素,但您将模板附加到其他元素。由于目标元素位于该模板中,而该模板没有附加到视图的
el
,因此事件将永远不会冒泡到委托给它的处理程序中


除此之外,正如@mu太短所指出的,当您执行
$(parent.append)(this.template)时,,
this.template
是模板函数。实际上,您应该使用数据调用它来获取模板。 您不应该使用像
$(“”)
这样的全局选择器,而应该使用
this.$el.find(“”)
作为最佳实践

另外,
选项
仅在
初始化
方法内部可用,在
未定义
外部可用

不要将父对象传递到视图中,然后将其自身附加到父对象,而是在视图外部执行此操作,并使视图独立

最好在视图中声明属性,而不是在创建后添加属性

并且不需要手动将事件处理程序的上下文绑定到视图,默认情况下,事件处理程序的上下文将是视图

您的视图应该如下所示:

define([ "jquery", "backbone", "text!../../pages/header.html" ], function($,
    Backbone, headerTpl) {

  var header = Backbone.View.extend({
    initialize : function(options) {
        this.render();
    },
    template: _.template(headerTpl),
    events : {
        "click #enBtn":"swichToEnglish",
        "click #frBtn":"swichToFrench"
    },
    render : function() {
        this.$el.append(this.template(/* pass the data here*/));
     //--------^----- this is required for the events to work
        return this;
    },
    swichToFrench:function(){
        if(i18n.currentLocal == 'en'){
            i18n.currentLocal='fr';
            this.$el.find("#frBtn").css("pointer-events","auto");
            this.render();
        }
    },
    swichToEnglish:function(){
        if(i18n.currentLocal == 'fr'){
          i18n.currentLocal='en';
          this.$el.find("#enBtn").css("pointer-events","auto");
          this.$el.find("#frBtn").css("pointer-events","none");
          this.render();
      }   
    }
  });

  return header;
});
您可以像这样创建:

self._header = new Header();
$(".main_container").append(self._header.el);

看起来您只想将视图内容添加到
“.main_container”
,而不需要其他元素。在这种情况下,您可以让视图
el
指向它,而不是通过在如下选项中将其作为
el
传递来创建新元素:

self._header = new Header({
 el: '.main_container' // this.el will refer to `.main_container` in view
});
然后您不必执行
$(“.main\u container”).append(self.\u header.el)


如果出于某种原因必须将父级作为选项传递到视图中,则应将其缓存在
initialize
内的视图中,以便在其他地方引用它,如

this.parent = options.parent

旁注:

如您所见,我已经更改了您声明视图属性的顺序-
initialize
,然后是template、event和render

我们初始化视图,创建模板函数,声明要委派的事件,然后呈现视图


您定义属性的顺序在内部并不重要,但是当其他开发人员查看您的代码时,它更容易理解。但是这是一个意见问题。

(1)
这个模板将是一个函数,而不是一段HTML。(2) 模板是什么样子的?This.template是一个使用文本库的html加载,您可以在require声明(1)中看到它
表示
此.template
将是一个函数,而不是字符串。(2) 但是模板实际上是什么样子的呢?(3) 有时还使用
parent
参数调用
render
,有时不使用该参数,也会调用
$('enBtn')
,而实际上应该使用
this。$('enBtn'))
。我所说的模板是指不同的视图,每个视图都有自己的html,并且每次调用其他视图时都会加载这些视图。关于渲染函数,你是对的,我修复了它,并调用以显示正确的语言,正如你所看到的,我使用的是i18Thank,它可以工作,但它会将页眉添加到页面底部,而不会替换现有的页眉(我有两个标题,一个在页面顶部,一个在页面末尾,因为我们使用的是append,当我使用.html时,它只显示标题,其余的消失了)当我选择另一种语言时,有没有办法呈现整个页面。Thnx:)@ELKamel我不知道到底是什么问题。。但是,如果您希望页眉位于顶部而不是底部,请使用
prepend()
而不是
append()
。?不,这不是问题,问题是页眉可能会重复,而不是被替换。empty()不起作用