我把我的头发拉出来,我似乎不能让鼠标事件工作后,我的 Backbone.js 视图是重新渲染,除非我做了最荒谬的事情:
$("a").die().unbind().live("mousedown",this.switchtabs);
我实际上有这个在那里,但决定更新到最新的 Backbone ,并尝试使用新的delegateEvents()
功能。
下面是我的项目ID的结构:
Appview / AppRouter
|
----->PageCollection
|
------->PageView/PageModel
------->PageView/PageModel these page view/models are not rendered
------->PageView/PageModel
|
------->PageView/PageModel
|
----->render() *when a pageview is rendered*
|
-----> Creates new
Tabcollection
|
--->TabModel/TabView <-- this is where the issue is
实际情况是tabcollection有一个主tabview来管理所有的选项卡,然后为每个选项卡创建一个新的模型/视图,并在每次加载选项卡时放置一个侦听器来重新呈现tabview。如果tabview被重新呈现,那么鼠标事件就不再起作用,除非我在其中放置那个人为的jQuery语句。
这是Tabview和渲染(我已经把它剥离了很多)
var TabPanelView = Backbone.View.extend({
className: "tabpanel",
html: 'no content',
model: null,
rendered: false,
events:{
'click a.tab-nav': 'switchtabs'
},
initialize: function(args)
{
this.nav = $("<ol/>");
this.views = args.items;
this.className = args.classname?args.classname:"tabpanel";
this.id = args.id;
this.container = $("<section>").attr("class",this.className).attr("id",this.id);
_.bindAll(this);
return this.el
},
/*
This render happens multiple times, the first time it just puts an empty html structure in place
waiting for each of the sub models/views to load in (one per tab)
*/
render: function(args){
if(!args)
{
//first render
var nav = $("<aside/>").addClass("tab-navigation").append("<ol/>").attr("role","navigation");
var tabcontent = $("<section/>").addClass("tab-panels");
for(i = 0;i<this.views.length;i++)
{
$("ol",nav).append("<li><a rel='"+this.views[i].id+"' href='javascript:;' class='tab-nav'></a></li>");
tabcontent.append(this.views[i].el);
}
this.$el.empty().append(nav).append(tabcontent);
}
else if(args && args.update == true){
// partial render -- i.e. update happened inside of child objects
var targetid = args.what.cid;
for(i = 0;i<this.views.length;i++)
{
var curcontent = this.$el.find("div#"+this.views[i].id);
var curlink = this.$el.find("a[rel='"+this.views[i].id+"']")
if(this.views[i].cid == targetid)
{
curcontent.html($(this.views[i].el).html());
curlink.text(this.views[i].model.rawdata.header);
}
if(i>0)
{
// set the first panel
curcontent.addClass("tab-content-hide");
}
if(i==0)
{
curcontent.addClass("tab-content-show");
curlink.addClass("tab-nav-selected");
}
// this ridiculous piece of jQuery is the *ONLY* this i've found that works
//$("a[rel='"+this.views[i].id+"']").die().unbind().live("mousedown",this.switchtabs);
}
}
this.delegateEvents();
return this;
},
switchtabs: function(args){
var tabTarget = args.target?args.target:false
if(tabTarget)
{
this.$el.find("aside.tab-navigation a").each(function(a,b)
{
$(this).removeClass("tab-nav-selected")
})
$(tabTarget).addClass("tab-nav-selected");
this.$el.find("div.tab-content-show").removeClass("tab-content-show").addClass("tab-content-hide");
this.$el.find("div#"+tabTarget.rel).removeClass("tab-content-hide").addClass("tab-content-show");
}
}
});
有人能想到为什么 Backbone.js 鼠标事件根本不触发吗?是因为它们不在DOM上吗?我认为这是 Backbone.js 特别有用的地方?...
3条答案
按热度按时间von4xj4u1#
下面这行代码可能就是您的问题所在:
this.delegateEvents();
把那个移走,它应该能用。
只有当你的事件与你的视图的
events
散列分开声明时,你才需要自己调用delegateEvents
。当你创建一个视图示例时, Backbone.js 的视图会为你调用这个方法。inkz8wg92#
当重新呈现视图时,是重用同一个视图并再次调用render(),还是删除该视图并创建一个全新的视图?
无论哪种方式,看起来原因都是视图事件在视图重新呈现之前没有被解除绑定。
重新渲染时,1)确保取消绑定旧视图中的所有事件,2)创建新视图并进行渲染
ljo96ir53#
当使用
$(el).empty()
时,它会删除选定元素中的所有子元素**,并删除所有绑定到选定元素(el
)内任何(子)元素的事件**(和数据)。若要保留系结至子项目的事件,但仍要移除子项目,请用途:
$(el).children().detach();
而不是$(.el).empty();
这将允许您的视图成功地重新呈现,并且事件仍在绑定和工作。