我第一次尝试使用Backbone.js,我遇到了一些麻烦。我不知道我的问题是我是不是在理解骨干应该如何工作,或者它只是一个代码问题。
我正在尝试创建一个动态菜单,使用它的项目创建主菜单栏没有问题,但是当我将其中一个菜单项悬停时,我无法触发悬停事件。
视图
var MenuView = Backbone.View.extend({
initialize: function(items) {
this.menu = items;
//Main navigation bar
this.el = $("#main-nav");
this.trigger('start');
this.render();
},
render: function() {
var me = this;
_.each(this.menu, function(mi) {
mi.render(me.el);
});
return this;
},
handleHover: function(e) {
console.debug(e);
}
});
var MenuItemView = Backbone.View.extend({
tagName: 'li',
className:'menu-item',
events: { //none of these work
'hover a':'handleHover',
'mouseover a':'handleHover',
'mouseover':'handleHover',
'click': 'handleHover',
'click a': 'handleHover'
},
initialize: function(mi) {
this.menuItem = mi;
this.el = $("<li class=\"menu-item\"></li>")
},
render: function(parent) {
this.el.append('<a href="' + this.menuItem.get("link") + '">' + this.menuItem.get("text") + '</a>');
parent.append(this.el);
return this;
},
handleHover: function(ev) {
console.debug("Hovering! " + ev + this.menuItem.get("cid"));
console.debug(ev);
return false;
}
});
模型
var MenuItem = Backbone.Model.extend({
defaults: {
parent: null,
children: [],
link: "",
text: ""
}
});
启动代码
$(document).ready(function() {
var menu = new MenuView([
new MenuItemView( new MenuItem({link: "/", text: "Home"})),
new MenuItemView( new MenuItem({link: "/", text: "Users"})),
new MenuItemView( new MenuItem({link: "/", text: "Configuration"}))
]);
});
任何帮助将不胜感激!
谢谢!
更新
好的,在MenuItemView视图上取el
方法之外的initialize
定义之后,它可以工作,但同一个元素在视图的所有实例上都被重用,所以我不得不改变以下代码的视图,以使其按照我想要的方式工作:
var MenuItemView = Backbone.View.extend({
events: { //none of these work
'hover a':'handleHover',
'mouseover a':'handleHover',
'mouseover':'handleHover',
'click': 'handleHover',
'click a': 'handleHover'
},
el: $('<li class="menu-item"></li>'),
initialize: function(mi) {
this.menuItem = mi;
this.el = $(this.el).clone(true);
},
render: function(parent) {
this.el.append('<a href="' + this.menuItem.get("link") + '">' + this.menuItem.get("text") + '</a>');
parent.append(this.el);
return this;
},
handleHover: function(ev) {
console.debug("Hovering! " + ev + this.menuItem.get("cid"));
console.debug(ev);
return false;
}
});
我必须在新实例上克隆元素吗?
答案 0 :(得分:10)
悬停不是正常事件,而是jquery提供的“便利”事件。它是mouseenter和mouseleave的结合。
绑定到mouseenter和mouseleave而不是悬停将满足你的需要。
答案 1 :(得分:8)
Re:“为什么我必须在新实例上克隆元素?”
基本问题就在这里:
var MenuItemView = Backbone.View.extend({
// ...
el: $('<li class="menu-item"></li>'),
在定义$('<li class="menu-item"></li>')
时执行MenuItemView
调用,因此您最终只能在$('<li>')
的所有实例之间共享一个MenuItemView
。
如果您在el
或initialize
内创建render
,那么您必须使用delegateEvents
手动绑定事件:
默认情况下,在{...]
的View构造函数中调用delegateEvents
因此,如果您自己创建this.el
,那么您必须自己致电this.delegateEvents()
。例如:
var MenuItemView = Backbone.View.extend({
// ...
render: function() {
this.el = $('<li class="menu-item"><a>' + this.cid + '</a></li>');
this.delegateEvents();
return this;
},
//...
});
演示:http://jsfiddle.net/ambiguous/RPqMh/2/
但是,如果您this.el
withDataAndEvents
开启了var MenuItemView = Backbone.View.extend({
el: $('<li class="menu-item"></li>'),
// ...
initialize: function() {
this.el = this.el.clone(true);
this.el.append('<a>' + this.cid + '</a>');
},
//...
});
标记,那么您应该没问题:
this.el.clone()
演示:clone
但是如果你只是var MenuItemView = Backbone.View.extend({
el: $('<li class="menu-item"></li>'),
// ...
initialize: function() {
this.el = this.el.clone();
this.el.append('<a>' + this.cid + '</a>');
},
// ...
});
,它将无效,因为http://jsfiddle.net/ambiguous/hCW3F/1/不会绑定到克隆:
delegateEvents
演示:delegate
但是如果你添加自己的var MenuItemView = Backbone.View.extend({
el: $('<li class="menu-item"></li>'),
// ...
initialize: function() {
this.el = this.el.clone();
this.el.append('<a>' + this.cid + '</a>');
},
render: function() {
this.delegateEvents();
return this;
},
// ...
});
电话,你就可以了:
{{1}}
答案 2 :(得分:2)
在我看来,你不需要这个属性:
tagName: 'li',
className:'menu-item'
如果您指定this.el = $('<li class="menu-item"></li>')
; ,请在MenuItemView中