浏览器的后退按钮破坏了我的 Backbone / Marionette 应用程序
Browser's back button break my Backbone / Marionette app
我正在使用 Backbone 和 Marionette 以及服务器 Rails 上的 Ruby 构建网络应用程序。
该应用运行良好,除了后退浏览器(FF、Chrome、IE11)的后退按钮会破坏一切。
这是一个重现问题的非常简单的示例:
var TestApp = new Marionette.Application();
TestApp.addRegions({
mainRegion: "#main-region"
});
TestApp.navigate = function(route, options){
options || (options = {});
Backbone.history.navigate(route, options);
};
TestApp.getCurrentRoute = function(){
return Backbone.history.fragment
};
TestApp.on("start", function(){
if(Backbone.history){
Backbone.history.start();
if(this.getCurrentRoute() === ""){
this.navigate("foo");
TestApp.MyApp.Show.Controller.ShowFoo();
}
}
});
TestApp.module("MyApp", function(App, TestApp, Backbone, Marionette, $, _) {
App.Router = Marionette.AppRouter.extend({
appRoutes: {
"foo": "ShowFoo",
"bar": "ShowBar",
"baz": "ShowBaz"
}
});
var API = {
ShowFoo: function(){
App.Show.Controller.ShowFoo();
},
ShowBar: function(){
App.Show.Controller.ShowBar();
},
ShowBaz: function(){
App.Show.Controller.ShowBaz();
}
};
TestApp.addInitializer(function(){
new App.Router({
controller: API
});
});
});
TestApp.module("MyApp.Show", function(Show, App, Backbone, Marionette, $, _)
{
Show.FooLayoutView = Backbone.Marionette.LayoutView.extend({
template: "#templates-foo",
tagName: "span"
});
Show.BarLayoutView = Backbone.Marionette.LayoutView.extend({
template: "#templates-bar",
tagName: "span"
});
Show.BazLayoutView = Backbone.Marionette.LayoutView.extend({
template: "#templates-baz",
tagName: "span"
});
var ContactsShowController = Marionette.Controller.extend({
ShowFoo: function()
{
this.fooView = new Show.FooLayoutView();
App.mainRegion.show(this.fooView);
},
ShowBar: function()
{
this.barView = new Show.BarLayoutView();
App.mainRegion.show(this.barView);
},
ShowBaz: function()
{
this.bazView = new Show.BazLayoutView();
App.mainRegion.show(this.bazView);
}
});
Show.Controller = new ContactsShowController;
});
$(function() {
TestApp.start();
});
<h1>Test the browser's back button.</h1>
<div id="main-region"></div>
<script type="text/template" id="templates-foo">
<p>
F O O
</p>
<p>
<a href="#bar">-> Bar</a>
</p>
</script>
<script type="text/template" id="templates-bar">
<p>
B A R
</p>
<p>
<a href="#baz">-> Baz</a>
</p>
</script>
<script type="text/template" id="templates-baz">
<p>
B A Z
</p>
<p>
Press the back button on your browser. You should go back to BAR, but the view is not shown.
</p>
</script>
上面的代码片段可能无法直接运行,您需要包含 Backbone 和 MarionetteJS.
我正在使用这些版本的库:
- underscore.js 1.7.0
- backbone.js 1.1.2
- backbone.marionette.js 2.2.2
因此,如果您加载该应用程序,您应该会看到 "F O O",单击 link 找到 Bar,单击 link 找到 Baz。
您现在应该在最后一页显示 "B A Z"。
现在单击浏览器上的后退按钮。 url 应该会变回 #bar,但您也应该会看到 "B A R",但是 #main-region 是空的。
我该如何解决这个问题?
我愿意更新库。坦率地说,我也处于将 backbone 和 marionette 扔进垃圾桶并重新编码一切的边缘 javascript + jQuery... 但是我,d不想。
感谢您的帮助。
纪尧姆
更新: 根据评论,很明显罪魁祸首是 OP 的 rails 安装附带的一个附加组件。
我建议他删除项目中的 rails/turbolinks
库,因为它似乎会干扰正确的页面重新加载。
使用您的代码制作了 fiddle 并包含了您发布的相同库。我没有改变任何东西,它就像魔术一样工作。
我也用过jQuery 2.1.0
你的版本是多少?
见 fiddle.
我正在使用 Backbone 和 Marionette 以及服务器 Rails 上的 Ruby 构建网络应用程序。
该应用运行良好,除了后退浏览器(FF、Chrome、IE11)的后退按钮会破坏一切。
这是一个重现问题的非常简单的示例:
var TestApp = new Marionette.Application();
TestApp.addRegions({
mainRegion: "#main-region"
});
TestApp.navigate = function(route, options){
options || (options = {});
Backbone.history.navigate(route, options);
};
TestApp.getCurrentRoute = function(){
return Backbone.history.fragment
};
TestApp.on("start", function(){
if(Backbone.history){
Backbone.history.start();
if(this.getCurrentRoute() === ""){
this.navigate("foo");
TestApp.MyApp.Show.Controller.ShowFoo();
}
}
});
TestApp.module("MyApp", function(App, TestApp, Backbone, Marionette, $, _) {
App.Router = Marionette.AppRouter.extend({
appRoutes: {
"foo": "ShowFoo",
"bar": "ShowBar",
"baz": "ShowBaz"
}
});
var API = {
ShowFoo: function(){
App.Show.Controller.ShowFoo();
},
ShowBar: function(){
App.Show.Controller.ShowBar();
},
ShowBaz: function(){
App.Show.Controller.ShowBaz();
}
};
TestApp.addInitializer(function(){
new App.Router({
controller: API
});
});
});
TestApp.module("MyApp.Show", function(Show, App, Backbone, Marionette, $, _)
{
Show.FooLayoutView = Backbone.Marionette.LayoutView.extend({
template: "#templates-foo",
tagName: "span"
});
Show.BarLayoutView = Backbone.Marionette.LayoutView.extend({
template: "#templates-bar",
tagName: "span"
});
Show.BazLayoutView = Backbone.Marionette.LayoutView.extend({
template: "#templates-baz",
tagName: "span"
});
var ContactsShowController = Marionette.Controller.extend({
ShowFoo: function()
{
this.fooView = new Show.FooLayoutView();
App.mainRegion.show(this.fooView);
},
ShowBar: function()
{
this.barView = new Show.BarLayoutView();
App.mainRegion.show(this.barView);
},
ShowBaz: function()
{
this.bazView = new Show.BazLayoutView();
App.mainRegion.show(this.bazView);
}
});
Show.Controller = new ContactsShowController;
});
$(function() {
TestApp.start();
});
<h1>Test the browser's back button.</h1>
<div id="main-region"></div>
<script type="text/template" id="templates-foo">
<p>
F O O
</p>
<p>
<a href="#bar">-> Bar</a>
</p>
</script>
<script type="text/template" id="templates-bar">
<p>
B A R
</p>
<p>
<a href="#baz">-> Baz</a>
</p>
</script>
<script type="text/template" id="templates-baz">
<p>
B A Z
</p>
<p>
Press the back button on your browser. You should go back to BAR, but the view is not shown.
</p>
</script>
我正在使用这些版本的库:
- underscore.js 1.7.0
- backbone.js 1.1.2
- backbone.marionette.js 2.2.2
因此,如果您加载该应用程序,您应该会看到 "F O O",单击 link 找到 Bar,单击 link 找到 Baz。 您现在应该在最后一页显示 "B A Z"。 现在单击浏览器上的后退按钮。 url 应该会变回 #bar,但您也应该会看到 "B A R",但是 #main-region 是空的。
我该如何解决这个问题?
我愿意更新库。坦率地说,我也处于将 backbone 和 marionette 扔进垃圾桶并重新编码一切的边缘 javascript + jQuery... 但是我,d不想。
感谢您的帮助。
纪尧姆
更新: 根据评论,很明显罪魁祸首是 OP 的 rails 安装附带的一个附加组件。
我建议他删除项目中的 rails/turbolinks
库,因为它似乎会干扰正确的页面重新加载。
使用您的代码制作了 fiddle 并包含了您发布的相同库。我没有改变任何东西,它就像魔术一样工作。
我也用过jQuery 2.1.0
你的版本是多少?
见 fiddle.