[英]AngularJS app breaks the back button when used for a single page application within another website
注意:我使用的是AngularJS v1.6.0
我已經在另一個現有網站上實現了一個獨立的AngularJS應用程序,它存在於網站的單個頁面上,而網站的其余部分沒有運行任何Angular代碼。
例如,網站上的常規頁面可能位於:
http://example.com/any-page
然后用戶可以單擊一個鏈接,然后將它們帶到運行Angular JS的頁面:
http://example.com/angularjs-app
登陸此URL時,它會加載AngularJS應用程序並按預期將#!/
附加到URL。 它不包含來自網站其余部分的任何元素,例如標題,因此對於用戶來說,它看起來像一個完全不同的部分。 然而它也打破了后退按鈕。 回到http://example.com/any-page
不可能的。 每次按下時,它只會再次加載AngularJS應用程序的着陸視圖 - 實際上用戶會卡在AngularJS應用程序頁面上,無法返回/any-page
。
我認為這與AngularJS路由有關,因為當你按下它時它似乎刷新了URL的#!/
部分,只是在應用程序上重新加載初始視圖。 但我可能是錯的。
請注意,在訪問各種路線時,后退按鈕在AngularJS應用程序中正常工作。 例如,如果我在應用程序中的各種路徑/視圖之間導航,例如#!/login
或#!/view-details
,我總是可以通過后退按鈕返回這些視圖。 但是當它達到初始視圖時,它就會停止工作。
有沒有人知道這方面的方法?
注意:我已經查看了其他各種Stack Overflow帖子,但是它們似乎都被隱藏了后退按鈕根本不工作,而不是這個問題,后退按鈕用於在應用程序內的路線之間導航,但不回來到網站上原來的非AngularJS頁面。
路由配置
(function () {
"use strict";
var routes = {
error: "/error",
forgottenPassword: "/forgotten-password",
home: "/home",
login: "/login",
orders: "/orders",
paymentDetails: "/payment-details",
personalDetails: "/personal-details",
subscriptions: "/subscriptions",
updatePassword: "/update-password",
accountVerification: "/account-verification",
register: '/register',
profile: '/profile',
accountConfirm: '/account-confirm',
deleteAccount: '/delete-account'
};
var configFunc = function (
$routeProvider,
$locationProvider,
CONFIG,
ROUTES) {
var resolve = {
isLoggedIn: [
"$q", "ERRORS", "core.services.sessionsService", function ($q, ERRORS, sessionsService) {
return sessionsService.isLoggedIn().then(function (isLoggedIn) {
if (isLoggedIn) {
return isLoggedIn;
}
return $q.reject({ error: ERRORS.route.requiresAuth });
});
}
]
};
var getTemplateUrl = function(page) {
return CONFIG.rootPagesUrl + page;
};
$routeProvider
.when("/", {
controller: "StartCtrl",
template: ""
})
.when(ROUTES.login, {
templateUrl: getTemplateUrl("login.html"),
pageName: "Login"
})
.when(ROUTES.forgottenPassword, {
templateUrl: getTemplateUrl("forgotten-password.html"),
pageName: "Forgotten Password"
})
.when(ROUTES.home, {
templateUrl: getTemplateUrl("home.html"),
resolve: resolve
})
.when(ROUTES.personalDetails, {
templateUrl: getTemplateUrl("personal-details.html"),
resolve: resolve
})
.when(ROUTES.paymentDetails, {
templateUrl: getTemplateUrl("payment-details.html"),
resolve: resolve
})
.when(ROUTES.orders, {
templateUrl: getTemplateUrl("orders.html"),
resolve: resolve
})
.when(ROUTES.subscriptions, {
templateUrl: getTemplateUrl("subscriptions.html"),
resolve: resolve
})
.when(ROUTES.updatePassword, {
templateUrl: getTemplateUrl("update-password.html"),
pageName: "Update Password"
})
.when(ROUTES.accountVerification, {
templateUrl: getTemplateUrl("account-verification.html"),
pageName: "Account Verification"
})
.when(ROUTES.error, {
templateUrl: getTemplateUrl("error.html"),
pageName: "Error"
})
.when(ROUTES.register, {
templateUrl: getTemplateUrl("register.html"),
pageName: "Register"
})
.when(ROUTES.profile, {
templateUrl: getTemplateUrl("profile.html"),
resolve: resolve,
pageName: "Profile"
})
.when(ROUTES.accountConfirm, {
templateUrl: getTemplateUrl("accountConfirm.html"),
pageName: "Registration Complete"
})
.when(ROUTES.deleteAccount, {
templateUrl: getTemplateUrl("deleteAccount.html"),
resolve: resolve,
pageName: "Delete Account"
})
.otherwise({
templateUrl: getTemplateUrl("login.html"),
pageName: "Login"
});
};
var config = [
"$routeProvider",
"$locationProvider",
"CONFIG",
"ROUTES",
configFunc
];
var module = angular.module("app");
module.constant("ROUTES", routes);
module.config(config);
})();
ng-view存在的索引部分:
<body ng-app="app" ng-strict-di>
<div>
<div id="container" class="mpp-app">
<div class="mpp-page" id="mpp-page">
<div class="page-wrapper">
<div class="ui-module-container">
<div brand></div>
</div>
<div ng-view></div>
</div>
</div>
<div class="ui-module-container">
<div footer></div>
</div>
</div>
</div>
<div id="spinner" class="hidden"><div class="icon"></div></div>
StartCtrl
(function () {
"use strict";
var func = function (
$rootScope,
$scope,
$location,
ROUTES,
APP_EVENTS,
CORE_EVENTS,
SessionModel,
sessionsService,
configurationAggregator) {
var broadcast = function(event, args) {
$rootScope.$broadcast(event, args);
};
var redirectToLogin = function() {
broadcast(APP_EVENTS.navigation.login);
};
// check if user is signed in and has a valid session
var verifySession = function() {
sessionsService.verify().then(function() {
// if user is logged in navigate to profile
// otherwise navigate to login
configurationAggregator.getConfiguration().then(function () {
broadcast(APP_EVENTS.auth.login.success);
//broad cast(APP_EVENTS.navigation.home);
broadcast(APP_EVENTS.navigation.uktvProfile);
}, redirectToLogin);
}, redirectToLogin);
};
// init
var sessionId = $location.search().guid;
if (angular.isDefined(sessionId) && sessionId !== null) {
broadcast(CORE_EVENTS.session.changed, { sessionId: sessionId });
verifySession();
} else {
verifySession();
}
};
var controller = [
"$rootScope",
"$scope",
"$location",
"ROUTES",
"EVENTS",
"mpp.core.EVENTS",
"mpp.core.SessionModel",
"mpp.core.services.sessionsService",
"mpp.core.aggregators.configurationAggregator",
func
];
var module = angular.module("app");
module.controller("StartCtrl", controller);
})();
這不是AngularJS路由器的問題(盡管可能是特定版本的錯誤,因此請在問題中添加有關版本的信息)。 但很可能你在路由器事件處理程序或StartCtrl
中有StartCtrl
。
AngularJS教程中的示例運行正常,您可以在此處獲取:
git clone https://github.com/angular/angular-phonecat.git
要本地化問題,我首先嘗試使用以下配置運行您的應用:
$routeProvider
.when('/', {
template: '<div>Hello</div>'
})
.when(ROUTES.login, {
templateUrl: getTemplateUrl("login.html"),
pageName: "Login"
})
.when(ROUTES.forgottenPassword, {
templateUrl: getTemplateUrl("forgotten-password.html"),
pageName: "Forgotten Password"
})
.when(ROUTES.home, {
templateUrl: getTemplateUrl("home.html"),
resolve: resolve
})
.when(ROUTES.personalDetails, {
templateUrl: getTemplateUrl("personal-details.html"),
resolve: resolve
})
.when(ROUTES.paymentDetails, {
templateUrl: getTemplateUrl("payment-details.html"),
resolve: resolve
})
.when(ROUTES.orders, {
templateUrl: getTemplateUrl("orders.html"),
resolve: resolve
})
.when(ROUTES.subscriptions, {
templateUrl: getTemplateUrl("subscriptions.html"),
resolve: resolve
})
.when(ROUTES.updatePassword, {
templateUrl: getTemplateUrl("update-password.html"),
pageName: "Update Password"
})
.when(ROUTES.accountVerification, {
templateUrl: getTemplateUrl("account-verification.html"),
pageName: "Account Verification"
})
.when(ROUTES.error, {
templateUrl: getTemplateUrl("error.html"),
pageName: "Error"
})
.when(ROUTES.register, {
templateUrl: getTemplateUrl("register.html"),
pageName: "Register"
})
.when(ROUTES.profile, {
templateUrl: getTemplateUrl("profile.html"),
resolve: resolve,
pageName: "Profile"
})
.when(ROUTES.accountConfirm, {
templateUrl: getTemplateUrl("accountConfirm.html"),
pageName: "Registration Complete"
})
.when(ROUTES.deleteAccount, {
templateUrl: getTemplateUrl("deleteAccount.html"),
resolve: resolve,
pageName: "Delete Account"
})
.otherwise({
templateUrl: getTemplateUrl("login.html"),
pageName: "Login"
});
如果它正常工作,那么你在StartCtrl控制器中有一些可疑的東西。 如果仍然無法正常工作,請嘗試以下方法:
$routeProvider
.when('/', {
template: '<div>Hello</div>'
})
.otherwise('/');
如果正常工作,那么查找$routeChangeError
處理程序。 如果沒有則可能是任何路由器事件處理程序。 以下是ngRoute的事件列表: $routeChangeStart
, $routeChangeError
, $routeUpdate
, $routeChangeSuccess
編輯:
由於您不希望用戶在單擊返回時返回/
路由,您可以將其從歷史記錄中刪除。 當您將用戶從/
route重定向時,只需在$location
服務上調用replace方法 。 例如$location.path('/login').replace()
。
你可以禁用#!
的前置#!
通過啟用HTML5Mode 。 我不是100%確定這是否與您的問題兼容,但這樣,打開Angular應用程序看起來像一個歷史事件,而不是兩個。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.