Javascript 主干视图事件不';重新渲染后无法工作
我很紧张,在视图重新渲染后,我似乎无法让鼠标事件在我的主干视图上工作,除非我做了最荒谬的事情:Javascript 主干视图事件不';重新渲染后无法工作,javascript,javascript-events,backbone.js,jquery,underscore.js,Javascript,Javascript Events,Backbone.js,Jquery,Underscore.js,我很紧张,在视图重新渲染后,我似乎无法让鼠标事件在我的主干视图上工作,除非我做了最荒谬的事情: $("a").die().unbind().live("mousedown",this.switchtabs); 实际上,我有这个,但决定更新到最新的主干,并尝试使用新的delegateEvents()函数 以下是我的项目id的结构: Appview / AppRouter | ----->PageCollection | -----
$("a").die().unbind().live("mousedown",this.switchtabs);
实际上,我有这个,但决定更新到最新的主干,并尝试使用新的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
Appview/AppRouter
|
----->页面收集
|
------->页面视图/页面模型
------->页面视图/页面模型不呈现这些页面视图/模型
------->页面视图/页面模型
|
------->页面视图/页面模型
|
----->呈现页面视图时呈现()*
|
----->创造新的
Tabcollection
|
--->TabModel/TabView当视图被重新渲染时,您是重复使用同一视图并再次调用render(),还是删除视图并创建一个全新的视图
无论哪种情况,原因似乎是视图事件在重新渲染视图之前未解除绑定。德里克·贝利对此有很好的理解
重新渲染时,1)确保解除旧视图中所有事件的绑定,2)创建一个新视图并渲染它这行代码可能是您的问题:
this.delegateEvents()代码>
去掉它,它应该会工作
您需要自己调用delegateEvents
的唯一时间是当您拥有与视图的events
散列分开声明的事件时。当您创建视图实例时,主干视图将为您调用此方法。当使用$(el).empty()
时,它将删除所选元素中的所有子元素,并删除绑定到所选元素内部任何(子)元素的所有事件(和数据)(el
)
若要将事件绑定到子元素,但仍要删除子元素,请使用:
$(el).children().detach();
而不是$(.el).empty();
这将允许您的视图在事件仍然绑定并工作的情况下成功重新渲染。到目前为止,您采取了哪些步骤来解决此问题?我将尝试以下几件事:查看是否可以在处理事件的主干源中设置断点。这可能会给您一些启示。另外,尝试使用Chrome的DOM和事件侦听器断点。这可能会帮助您检查是否有任何代码正在执行,或者事件是否只是无法连接。我已根据jq$(document.find)记录(“tab nav selected”)要查看呈现的项是否实际在dom上..可以得到正确的结果。在我自己的代码中,已通过断点。我没有足够的信心使用调试器挖掘主干本身。范围似乎都很好…我不确定,但似乎事件正在被重写但是,我不能在每个子视图更新时创建新的父视图(父视图必须响应子视图).奇怪的是,我在文章中尝试了这种方法,但奇怪的是,它每3次就工作1次,其他时候我重新加载了页面…没什么大不了的。很荣幸你能回答我的问题,我在你的博客上读到了一堆有用的主干内容。我已经放弃并使用jQuery。live…是的,这是一个讨厌的东西…但这是唯一的事情我正在工作,离截止日期还有两天。。humm@Alex在您的代码中尝试:this.$el.children().detach().append(nav).append(tabcontent);
它应该可以完美地工作。无需重新创建视图的实例。请查看这些答案作为进一步的参考:和
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");
}
}
});