Javascript 如何在浏览器刷新后恢复backbonejs完整路由
这是一个关于主干JS的架构问题:Javascript 如何在浏览器刷新后恢复backbonejs完整路由,javascript,backbone.js,Javascript,Backbone.js,这是一个关于主干JS的架构问题: AppView包含加载了LeadsView的DOM元素占位符 LeadsView包含要显示的DOM占位符LeadsView 我当前的路线是#app/leads/1,这意味着所有3个视图都已加载。AppView->LeadsView->LeadsView 现在,用户突然按下了浏览器的刷新按钮。路由器将尝试将其传送到#app/leads/:1,路由到“app/leads/:lead\u id:“showLeadView”,但AppView和LeadsView这次未呈
AppView
包含加载了LeadsView
的DOM元素占位符LeadsView
包含要显示的DOM占位符LeadsView
我当前的路线是#app/leads/1
,这意味着所有3个视图都已加载。AppView
->LeadsView
->LeadsView
现在,用户突然按下了浏览器的刷新按钮。路由器将尝试将其传送到#app/leads/:1
,路由到“app/leads/:lead\u id:“showLeadView”
,但AppView
和LeadsView
这次未呈现,因此LeadView
的呈现将失败
它正在寻找要将自身呈现到其中的DOM元素,但找不到它
如何用主干处理这个问题
蒂亚,
Nimrod。当点击“app/leads/:lead\u id:”showleadwiew“
路线时,您可以通过编程方式初始化和呈现其他视图
现在的问题是:如何查找视图是否已渲染
我通过向模型和集合中添加一个新属性来解决这个问题,该属性将告诉我它们是否已填充(如果已获取或已设置属性)。可以在中找到这方面的实现
看起来是这样的:
isPopulated: function() {
/*jshint -W089 */
// We are populated if we have attributes set
var attributes = _.clone(this.attributes),
defaults = getValue(this, 'defaults') || {};
for (var default_key in defaults) {
if (attributes[default_key] != defaults[default_key]) {
return true;
}
delete attributes[default_key];
}
var keys = _.keys(attributes);
return keys.length > 1 || (keys.length === 1 && keys[0] !== this.idAttribute);
}
if(!appModel.isPopulated())
this.showAppView();
if(!leadsCollection.isPopulated())
this.showLeadsView();
使用此方法,我可以验证渲染父视图所需的集合是否已填充。如果没有,则调用在导航到app
然后导航到leads
时将调用的方法(实际上,您可以通过编程方式访问路线)
它可能看起来像这样:
isPopulated: function() {
/*jshint -W089 */
// We are populated if we have attributes set
var attributes = _.clone(this.attributes),
defaults = getValue(this, 'defaults') || {};
for (var default_key in defaults) {
if (attributes[default_key] != defaults[default_key]) {
return true;
}
delete attributes[default_key];
}
var keys = _.keys(attributes);
return keys.length > 1 || (keys.length === 1 && keys[0] !== this.idAttribute);
}
if(!appModel.isPopulated())
this.showAppView();
if(!leadsCollection.isPopulated())
this.showLeadsView();
正如您所见,这意味着在路由器中保留对appModel
和leadsCollection
的引用
更新(澄清)
在我回答的第一行中,我提到了如下内容:
isPopulated: function() {
/*jshint -W089 */
// We are populated if we have attributes set
var attributes = _.clone(this.attributes),
defaults = getValue(this, 'defaults') || {};
for (var default_key in defaults) {
if (attributes[default_key] != defaults[default_key]) {
return true;
}
delete attributes[default_key];
}
var keys = _.keys(attributes);
return keys.length > 1 || (keys.length === 1 && keys[0] !== this.idAttribute);
}
if(!appModel.isPopulated())
this.showAppView();
if(!leadsCollection.isPopulated())
this.showLeadsView();
AppView
引用了一个子视图LeadsView
,该子视图引用了一个子视图LeadsView
- 在路由器中有一个
AppView
实例
- 您将
appModel
传递给AppView
并在点击app
路由器时调用.render()
- 您将
leadsCollection
传递给AppView.getLeadsView()
并在点击leads
路线时调用它的.render()
- 将右侧的
lead
模型从leadsCollection
传递到AppView.getLeadsView().getLeadsView()
并在点击路线时对其调用.render()
或者您可以使用类似胸部的东西
它已经添加了对子视图的处理(负责事件委派、事件销毁、DOM清理等),并为其提供了模板处理程序,以便您可以在模板中指向要呈现子视图的位置
我希望现在我的意思更清楚了,正如你所看到的,它回答了你的问题。你最初是如何表达所有这些观点的?显然不在路由处理程序中-这是您必须做的。你的路由器应该检查当前的路线,并决定如何相应地渲染视图。此外:“AppView,其中包含加载了LeadsView的DOM元素占位符。LeadsView包含用于显示LeadView的DOM占位符”
“在您直接指定目标元素时读取,如view.render();视图。$el.appendTo($(“#直接寻址元素”)
。考虑嵌套视图,然后将代码<代码>子视图.RelEd();子视图.el.appendTo(this.el);//其中,$el是当前视图
。你应该提供更多的视图代码和概述结构的路由器代码。谢谢@try catch最后你做对了,我没有呈现子视图,而是直接访问元素。好的捕获:-)我理解,但实际上我认为这不是正确的架构设计,事实上正如@try catch最后提到的,正确的方法是使用子视图,而不是直接访问这些视图上的dom元素。然而,我同意呈现和已经呈现的文档片段可能是多余的,为此,我们必须检查它是否还没有呈现。在我回答的第一行中,我提到的正是@try catch最后说的话。通过,您可以通过编程方式初始化和呈现其他视图(这意味着其他视图是子视图,您可以调用.render()
方法。正如我在回答中所说,你真正的问题是找到它们是否已经被渲染。为什么你不认为使用在路线被击中时渲染的子视图是糟糕的架构?更新了我的回答并澄清了这一点。顺便说一句,你的问题是如何做,而不是什么是最好的方法。