路由更改在 Promise 回调函数中不起作用

Posted

技术标签:

【中文标题】路由更改在 Promise 回调函数中不起作用【英文标题】:Route change does not work in promise callback function 【发布时间】:2015-02-18 03:13:42 【问题描述】:

我有一个登录屏幕,它接受用户名和密码并根据 Web 服务对其进行身份验证。如果 Web 服务返回“true”表示用户已通过身份验证,我想将用户重定向到登录的主页。代码如下:

var app = angular.module('app');
app.controller('loginCtrl', function ($scope, $location, UserService) 
    $scope.authUser = function () 
        UserService.AuthenticateUser($scope.Username, $scope.Password)
            .then(function (result) 
                // Check contents of HTTP response for "true".
                if (result.data == "true") 
                    // Web service returned "true" indicated user is authenticated; therefore, redirect to logged-in home page.
                    $location.path("/home");
                 else 
                    // Web service returned "false" indicating user is not authenticated.
                    alert("Authentication failed.");
                
            )
            .catch(function () 
                alert("Attempt to authenticate user failed.");
            );
    ;
);
app.factory('UserService', function ($http) 
    return 
        AuthenticateUser: function (username, password) 
            var url = "https://<redacted>/";
            var request = 
                "Username": username,
                "Password": password
            ;
            return $http.post(url + 'auth', request);
        
    ;
);

我的问题在于以下行:

$location.path("/home");

Web 服务工作正常,在调试器中命中该行,但没有发生路由更改。控制台中没有出现错误。

这与摘要生命周期有关吗?承诺如何运作?路由在应用程序的其他地方工作正常,只是当我在 $http 调用后尝试使用它时,它无法工作。这甚至是改变视图的正确角度模式吗?

路由:

$routeProvider
    .when('/home', 
        templateUrl: 'home.html'
    )
    .otherwise(
        templateUrl: 'login.html'
    );
$locationProvider.html5Mode(false);

【问题讨论】:

你在使用 angular ui-router 吗?还是默认的 angularjs 路由模块? 好问题...我使用的是默认路由器。来自 Angular 的一个名为 angular-route.js。我对 Angular 还很陌生,所以有点过头了。 您的浏览器网址更改了吗?还是两者之一? 浏览器url闪烁但不改变。它从 #/login 开始,闪烁,并保持在 #/login。 你有匹配“/home”的规则吗?你能粘贴你的路由器代码吗? 【参考方案1】:

您需要在更改网址后添加$scope.$apply()

$location.path("/home");
$scope.$apply()

$apply() 用于从外部以角度执行表达式 角度框架。 (例如来自浏览器 DOM 事件, setTimeout、XHR 或第三方库)。

但是,我建议你启用html5mode 并使用角度ui-router

编辑

如果你得到“digest already in progress”,把你的$location.path包装成$timeout,记得先注入它。

$timeout(function() 
  $location.path("/home");
) 

然后,您的 url 更改将在下一个摘要周期运行 safaly。 .

【讨论】:

如果我们使用 ui-router,我们是否必须将 $location 调用包装在 $scope.$apply() 中? @Rohan 如果你在第三方库函数中调用 $location,是的。

以上是关于路由更改在 Promise 回调函数中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

jquery $.post 在加载回调函数中不起作用?

回调 URL 在本地 Auth0 中不起作用

jQuery 地址在回调中不起作用

动画在 api 响应成功回调中不起作用

Facebook登录回调在钛合金中不起作用

JS中promise对象的作用与使用