在 $routeChangeStart 位置没有找到对应的模板

On $routeChangeStart location doesn't find the corresponding template

我有一个 Web 应用程序和一个带有模块 myAppapp 变量。
我有 3 页:/login/registration/。我的 $routeChangeStart 定义为如下所示:

  1. 检查是否定义了全局变量user,如果是则转到步骤4
  2. 检查用户想去的地方:如果他不想进入 /login/registration 执行 event.preventDefault() 并检查是否存在有效会话(通过cookie) 并尝试授权用户。如果用户被授权设置 user 全局变量并将他重定向到他想要的页面,否则将他发送到 /login 页面。
  3. 如果他想去 /login/registration 什么也不做(我们在这种情况下没有用户变量,我想登录或注册)。
  4. 检查用户想去哪里:如果他想进入 /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");
                        });