Backbone 单击事件未在模板视图中触发
Backbone click event not firing in template View
我正在开发一个基于动态模板的 Backbone 应用程序。我有一个 header 视图,一个侧面板视图和页脚视图,它们在调用任何其他视图时动态初始化。
问题是我在每个模板视图上都有未触发的事件。例如,我有一个按钮可以更改 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;
});
在路由器中调用 header 视图:
self._header = new Header({parent: $(".main_container")});
关于如何解决此问题的任何想法。我需要知道如何触发这些事件谢谢。
您的事件处理程序未触发的原因是事件处理程序被委托给视图元素,但您将模板附加到其他元素。由于目标元素位于未附加视图的模板中 el
,因此事件永远不会冒泡到委托给它的处理程序中。
除此之外,@mu 指出的太短了,当你这样做时 $(parent).append(this.template);
,
this.template
是模板函数。您实际上应该用数据调用它以获取模板。
并且您不应该使用像 $('')
这样的全局选择器,而应该使用 this.$el.find('')
作为最佳实践。
此外,options
仅在 initialize
方法内部可用,undefined
在外部。
与其将父级传递到视图中,然后将其自身附加到父级,不如在视图外执行此操作并使视图独立。
最好在视图中声明 template
属性 而不是在创建后添加它。
并且不需要手动将事件处理程序的上下文绑定到视图,默认情况下事件处理程序的上下文就是视图。
您的视图应如下所示:
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_container").append(self._header.el);
如果出于某种原因必须将父项作为选项传递到视图中,那么您应该将其缓存在 initialize
的视图中,以便您可以在其他地方引用它。
this.parent = options.parent
旁注:
如您所见,我更改了您声明视图属性的顺序 - initialize
在最上面,然后是模板、事件和渲染。
我们初始化视图,创建模板函数,声明要委托的事件,然后渲染视图。
您定义属性的顺序在内部并不重要,但当其他开发人员查看您的代码时,它更容易理解。不过见仁见智。
我正在开发一个基于动态模板的 Backbone 应用程序。我有一个 header 视图,一个侧面板视图和页脚视图,它们在调用任何其他视图时动态初始化。 问题是我在每个模板视图上都有未触发的事件。例如,我有一个按钮可以更改 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;
});
在路由器中调用 header 视图:
self._header = new Header({parent: $(".main_container")});
关于如何解决此问题的任何想法。我需要知道如何触发这些事件谢谢。
您的事件处理程序未触发的原因是事件处理程序被委托给视图元素,但您将模板附加到其他元素。由于目标元素位于未附加视图的模板中 el
,因此事件永远不会冒泡到委托给它的处理程序中。
除此之外,@mu 指出的太短了,当你这样做时 $(parent).append(this.template);
,
this.template
是模板函数。您实际上应该用数据调用它以获取模板。
并且您不应该使用像 $('')
这样的全局选择器,而应该使用 this.$el.find('')
作为最佳实践。
此外,options
仅在 initialize
方法内部可用,undefined
在外部。
与其将父级传递到视图中,然后将其自身附加到父级,不如在视图外执行此操作并使视图独立。
最好在视图中声明 template
属性 而不是在创建后添加它。
并且不需要手动将事件处理程序的上下文绑定到视图,默认情况下事件处理程序的上下文就是视图。
您的视图应如下所示:
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_container").append(self._header.el);
如果出于某种原因必须将父项作为选项传递到视图中,那么您应该将其缓存在 initialize
的视图中,以便您可以在其他地方引用它。
this.parent = options.parent
旁注:
如您所见,我更改了您声明视图属性的顺序 - initialize
在最上面,然后是模板、事件和渲染。
我们初始化视图,创建模板函数,声明要委托的事件,然后渲染视图。
您定义属性的顺序在内部并不重要,但当其他开发人员查看您的代码时,它更容易理解。不过见仁见智。