【发布时间】:2014-05-21 18:00:30
【问题描述】:
所以我有一个单页主干应用程序,它通过 AJAX 加载新页面并使用历史 API 更新 URL。这一切都很好,但是当我按下后退按钮时,它只是将 URL 更改回来并且不会加载以前的 AJAX。
所以我已经开始解决这个问题,但是我遇到了一个奇怪的问题,即调用了以前的 AJAX,正确加载但无法正常工作,因为我收到以下错误:
this.el is undefined
我真的不知道如何解决这个问题,这是我的一些代码:
ContainerView = Backbone.View.extend({
el: 'body',
events: {
'click .navigation-item': 'loadRequestedPage'
},
initialize: function() {
this.listenTo(Backbone, 'popstate', this.onPopState);
},
onPopState: function(e) {
var pageName = window.location.pathname.substring(window.location.pathname.lastIndexOf('/') + 1, window.location.pathname.lastIndexOf('php') + 3);
$('.navigation-item[href="'+pageName+'"]').eq(0).click();
},
....
loadRequestedPage: function(e) {
if (Modernizr.history) {
e.preventDefault();
var pageModel = myWebsite.where({pageID: currentPage})[0],
requestedPageID = $(e.currentTarget).data('page-id'),
requestedPageModel = myWebsite.where({pageID: requestedPageID})[0],
requestedPageUrl = requestedPageModel.get('pageUrl'),
$targetElement = this.determineTargetElement(requestedPageID);
this.closeMobileNavigation();
this.loadNewPage(requestedPageModel, requestedPageUrl, requestedPageID, $targetElement);
this.setActiveNavItem(requestedPageUrl);
this.updateCurrentPage(requestedPageID);
this.gaTrackEvent('Page Navigation', requestedPageUrl, 'User used the main navigation to navigate to' + requestedPageUrl);
}
},
loadRequestedPage 内部的函数继续触发history.pushstate,然后触发backbone.router,最后启动所需的view。
手动单击.navigation-item 时效果很好,但在单击后退按钮后通过 JS 触发时效果不佳。
如果有人能提供帮助,那就太棒了。
谢谢。
编辑
这是我的路由器
var app = app || {};
(function($) {
var Router = Backbone.Router.extend({
routes: {
'': 'instantiateHome',
'index.php': 'instantiateHome',
'our-approach.php': 'instantiateOurApproach',
'our-work.php': 'instantiateOurWork',
'people.php': 'instantiatePeople',
'social.php': 'instantiateSocial',
'contact-us.php': 'instantiateContactUs',
"*notFound" : 'notFound'
},
instantiateHome: function() {
if(app.home_view == null) {
app.home_view = new app.HomeView();
}
},
instantiateOurApproach : function() {
if(app.our_approach_view == null) {
app.our_approach_view = new app.OurApproachView();
}
},
instantiateOurWork: function() {
if(app.our_work_view == null) {
app.our_work_view = new app.OurWorkView();
}
},
instantiatePeople: function() {
if(app.people_view == null) {
app.people_view = new app.PeopleView();
}
},
instantiateSocial: function() {
if(app.social_view == null) {
app.social_view = new app.SocialView();
}
},
instantiateContactUs: function() {
if(app.contact_us_view == null) {
app.contact_us_view = new app.ContactUsView();
}
},
notFound: function() {
if(app.not_found_view == null) {
app.not_found_view = new app.NotFoundView();
}
}
});
app.router = new Router();
var location_pathname = window.location.pathname;
var site_url = location_pathname.replace(location_pathname.split("/").pop(),"");
var urlArray = location_pathname.split("/");
var pageUrl = urlArray[urlArray.length-1];
if (Modernizr.history) {
Backbone.history.start({pushState: true, root: site_url});
} else {
Backbone.history.start({hashChange: false, root: site_url});
}
app.router.navigate(pageUrl, {trigger: true});
})(jQuery);
编辑
所以我发现按下后退按钮会触发路由器,而无需执行以下代码:
app.router.navigate(pageUrl, {trigger: true});
通常我在 AJAX 调用完成后运行上面的代码,所以我知道在新视图实例化之前所有元素都在页面上。
所以我想我现在的问题是:如何阻止后退按钮触发路由器?
编辑
依赖ajaxComplete()的新路由器代码
instantiateOurWork: function() {
if (app.ajaxActive) {
$(document).ajaxComplete(function() {
if(app.our_work_view == null) {
app.our_work_view = new app.OurWorkView();
$(document).unbind('ajaxComplete');
}
});
} else {
if(app.our_work_view == null) {
app.our_work_view = new app.OurWorkView();
}
app.ajaxActive = true;
}
},
这确实是一个混乱的代码,但我不知道该怎么做。
【问题讨论】:
-
您的骨干路由器是什么样的?
-
@SteamDev 我已经为你添加了路由器。
-
所以问题是在ajax调用完成之前点击返回?你能像
if (view.isFetching) return;那样在路由器中添加一个检查吗? -
嘿@Vic - 感谢您的评论,所以我实际上已经将我的路由器更改为依赖
$(document).ajaxComplete()现在这意味着它可以工作,但它是非常混乱的代码,我会更新我的问题举个例子。我现在的问题是,当我快速按下后退按钮时,从以前的视图(如$.each())和类似的功能仍然运行,并导致错误
标签: javascript jquery ajax backbone.js