所以我有一个单页骨干应用程序,它通过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;
}
},
这是非常混乱的代码,但我不知道如何做到这一点。
答案 0 :(得分:0)
好的,所以我弄清楚了,这不是一个美丽的景象,但我不知道我还能怎么做。
首先,我需要确保在开始加载新视图之前所有ajax调用都已结束,这样可以防止任何时候存在多个视图并停止任何JS错误,这可以通过以下代码完成,这些代码也可以在我上面的一个编辑:
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;
}
},
app.ajaxActive
是一个全局变量,默认情况下设置为false,这是因为初始页面加载不执行AJAX调用,然后将其设置为true,这意味着它总是期望一个AJAX调用正在运行并等待它使用ajaxComplete
函数完成。
我必须处理的下一个问题是终止在后台运行的代码,例如getScript()
和$.each
循环会导致错误,因为他们会在查看后尝试运行除去。
要解决此问题,我必须实现默认情况下设置为this.stopExecution
的本地变量false
。
调用我的this.removeView()
函数时,this.stopExecution
将设置为true
。
然后在删除视图后可能运行的任何代码中,我添加了以下代码:
if(self.stopExecution) {
return false;
}
会阻止代码运行并防止出现任何错误。
如果有人有更好的解决方案,请随时分享。
感谢。