在 $routeChangeStart 位置没有找到对应的模板
On $routeChangeStart location doesn't find the corresponding template
我有一个 Web 应用程序和一个带有模块 myApp
的 app
变量。
我有 3 页:/login
、/registration
和 /
。我的 $routeChangeStart
定义为如下所示:
- 检查是否定义了全局变量
user
,如果是则转到步骤4
- 检查用户想去的地方:如果他不想进入
/login
或 /registration
执行 event.preventDefault()
并检查是否存在有效会话(通过cookie) 并尝试授权用户。如果用户被授权设置 user
全局变量并将他重定向到他想要的页面,否则将他发送到 /login
页面。
- 如果他想去
/login
或 /registration
什么也不做(我们在这种情况下没有用户变量,我想登录或注册)。
- 检查用户想去哪里:如果他想进入
/login
或 /registration
执行 event.preventDefault()
并将他重定向到主页 /
页面(用户有一个有效的会话,无需再次登录)。
逻辑运行良好,直到我们点击 F5
(我知道它擦除 $rootScope
,但以额外的 AJAX 调用为代价,我们应该没问题)在具有有效会话 cookie 的 /
页面中。应用程序根本没有重定向到正确的模板,页面保持空白。如果我们改为在 URL 中插入 /
旁边的任何内容(例如 /blah
),则一切正常。
这是我的 app.js
:
(function () {
angular.module("myApp", ["controllers", "services", "directives", "ngRoute"])
.config(["$httpProvider", "$routeProvider", function ($httpProvider, $routeProvider) {
$httpProvider.defaults.withCredentials = true;
$httpProvider.defaults.headers.post['Content-Type'] = 'application/json; charset=utf-8';
$routeProvider
.when("/login", {
controller: "LoginController",
templateUrl: "app/partials/login.html"
})
.when("/registration", {
controller: "RegistrationController",
templateUrl: "app/partials/registration.html"
})
.when("/", {
controller: "MainController",
templateUrl: "app/partials/home.html"
})
.otherwise("/");
}])
.run(function ($rootScope, $location, $http) {
$rootScope.$on('$routeChangeStart', function (event, next, current) {
if (!$rootScope.user) {
if (next && next.$$route && (next.$$route.originalPath !== "/login" && next.$$route.originalPath !== "/registration")) {
event.preventDefault();
$http.get("http://localhost:8080/myapp/api/user?self=true")
.success(function (data) {
$rootScope.user = data;
$location.path(next.$$route.originalPath);
})
.error(function () {
$location.path("/login");
});
}
}else{
if (next && next.$$route && (next.$$route.originalPath === "/login" || next.$$route.originalPath === "/registration")){
event.preventDefault();
$location.path("/");
}
}
});
});
angular.module("controllers", []);
angular.module("services", []);
angular.module("directives", [])
})();
为什么 .success()
AJAX 调用中的 $location.path(next.$$route.originalPath);
不起作用?请注意,如果我将其替换为例如$location.path("/blah");
它被正确重定向(但仍然不适用于 $location.path("/");
)。
$rootScope.$evalAsync(function() {
$location.path('/c');
});
这应该可以正常工作。
笔记:
event.preventDefault();
仅在 Angular 1.3+ 中起作用,但您不能直接更改 $location,需要 $evalAsync
我认为当您调用 event.preventDefault() 时 angular 会尝试退回到当前路径。但是,如果您是第一次进入,则当前路径未定义,因此 angular 将根路径 ("/") 作为当前路径。这样做,$location.path 会尝试去到 angular 带你去的同一个地方,结果什么也没做。
因此,最后您必须执行 $route.reload() 而不是 $location.path()。
$http.get("http://localhost:8080/myapp/api/user?self=true")
.success(function (data) {
$rootScope.user = data;
if ($location.path() === next.$$route.originalPath) {
$route.reload();
} else {
$location.path(next.$$route.originalPath);
}
})
.error(function () {
$location.path("/login");
});
我有一个 Web 应用程序和一个带有模块 myApp
的 app
变量。
我有 3 页:/login
、/registration
和 /
。我的 $routeChangeStart
定义为如下所示:
- 检查是否定义了全局变量
user
,如果是则转到步骤4
- 检查用户想去的地方:如果他不想进入
/login
或/registration
执行event.preventDefault()
并检查是否存在有效会话(通过cookie) 并尝试授权用户。如果用户被授权设置user
全局变量并将他重定向到他想要的页面,否则将他发送到/login
页面。 - 如果他想去
/login
或/registration
什么也不做(我们在这种情况下没有用户变量,我想登录或注册)。 - 检查用户想去哪里:如果他想进入
/login
或/registration
执行event.preventDefault()
并将他重定向到主页/
页面(用户有一个有效的会话,无需再次登录)。
逻辑运行良好,直到我们点击 F5
(我知道它擦除 $rootScope
,但以额外的 AJAX 调用为代价,我们应该没问题)在具有有效会话 cookie 的 /
页面中。应用程序根本没有重定向到正确的模板,页面保持空白。如果我们改为在 URL 中插入 /
旁边的任何内容(例如 /blah
),则一切正常。
这是我的 app.js
:
(function () {
angular.module("myApp", ["controllers", "services", "directives", "ngRoute"])
.config(["$httpProvider", "$routeProvider", function ($httpProvider, $routeProvider) {
$httpProvider.defaults.withCredentials = true;
$httpProvider.defaults.headers.post['Content-Type'] = 'application/json; charset=utf-8';
$routeProvider
.when("/login", {
controller: "LoginController",
templateUrl: "app/partials/login.html"
})
.when("/registration", {
controller: "RegistrationController",
templateUrl: "app/partials/registration.html"
})
.when("/", {
controller: "MainController",
templateUrl: "app/partials/home.html"
})
.otherwise("/");
}])
.run(function ($rootScope, $location, $http) {
$rootScope.$on('$routeChangeStart', function (event, next, current) {
if (!$rootScope.user) {
if (next && next.$$route && (next.$$route.originalPath !== "/login" && next.$$route.originalPath !== "/registration")) {
event.preventDefault();
$http.get("http://localhost:8080/myapp/api/user?self=true")
.success(function (data) {
$rootScope.user = data;
$location.path(next.$$route.originalPath);
})
.error(function () {
$location.path("/login");
});
}
}else{
if (next && next.$$route && (next.$$route.originalPath === "/login" || next.$$route.originalPath === "/registration")){
event.preventDefault();
$location.path("/");
}
}
});
});
angular.module("controllers", []);
angular.module("services", []);
angular.module("directives", [])
})();
为什么 .success()
AJAX 调用中的 $location.path(next.$$route.originalPath);
不起作用?请注意,如果我将其替换为例如$location.path("/blah");
它被正确重定向(但仍然不适用于 $location.path("/");
)。
$rootScope.$evalAsync(function() {
$location.path('/c');
});
这应该可以正常工作。
笔记:
event.preventDefault();
仅在 Angular 1.3+ 中起作用,但您不能直接更改 $location,需要 $evalAsync
我认为当您调用 event.preventDefault() 时 angular 会尝试退回到当前路径。但是,如果您是第一次进入,则当前路径未定义,因此 angular 将根路径 ("/") 作为当前路径。这样做,$location.path 会尝试去到 angular 带你去的同一个地方,结果什么也没做。
因此,最后您必须执行 $route.reload() 而不是 $location.path()。
$http.get("http://localhost:8080/myapp/api/user?self=true")
.success(function (data) {
$rootScope.user = data;
if ($location.path() === next.$$route.originalPath) {
$route.reload();
} else {
$location.path(next.$$route.originalPath);
}
})
.error(function () {
$location.path("/login");
});