gpt4 book ai didi

php - $stateChangeStart 在从 Rest API 获取数据之前运行

转载 作者:搜寻专家 更新时间:2023-10-31 21:53:16 27 4
gpt4 key购买 nike

我尝试进行用户登录身份验证,我创建了一个名为 AuthService 的服务,方法是 isAuthenticated,我在其中调用 API 进行交叉检查用户是否登录(稍后我将在其中使用用户 Angular 色),然后我在 $rootScope.$on 中调用此服务,但它不会等到我的服务从中获取数据API,这是我的 app.js

var app = angular.module('myApp', ['ngRoute', 'ui.router', 'ngAnimate', 'toaster', 'ui.bootstrap']);

app.config(['$routeProvider', '$locationProvider', '$stateProvider', '$urlRouterProvider',
function ($routeProvider, $locationProvider, $stateProvider, $urlRouterProvider) {
$stateProvider.
state('/', {
url: "/",
views: {
header: {
templateUrl: 'partials/common/header.html',
controller: 'authCtrl',
},
content: {
templateUrl: 'partials/dashboard.html',
controller: 'authCtrl',
}
},
title: 'Dashboard',
authenticate: true
})

.state('login', {
url: "/login",
views: {
content: {
templateUrl: 'partials/login.html',
controller: 'authCtrl',
}
},
title: 'Login',
authenticate: false
})

.state('dashboard', {
title: 'Dashboard',
url: "/dashboard",
views: {
header: {
templateUrl: 'partials/common/header.html',
controller: 'authCtrl',
},
content: {
templateUrl: 'partials/dashboard.html',
controller: 'authCtrl',
}
},
authenticate: true
});
$urlRouterProvider.otherwise("/");

//check browser support
if(window.history && window.history.pushState){
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
}
}])
.run(function ($rootScope, $location, $state, Data, AuthService) {
$rootScope.$on("$stateChangeStart", function (event, toState, toParams, fromState, fromParams) {
$rootScope.title = toState.title;
$rootScope.authenticated = false;
var userInfo = AuthService.isAuthenticated();
if (toState.authenticate && !AuthService.isAuthenticated()){
// User isn’t authenticated
$state.transitionTo("login");
event.preventDefault();
} else {
alert('here I am ='+$rootScope.authenticated);
}
});
});

这是我的服务

app.factory('AuthService', function ($http, Data, $rootScope) {
var authService = {};

authService.isAuthenticated = function () {
Data.get('index.php/api/authentication/is_login').then(function (results) {
if (results.uid) {
$rootScope.authenticated = true;
$rootScope.uid = results.uid;
$rootScope.name = results.name;
$rootScope.email = results.email;
return results.uid;
} else {
return false;
}
});
}
return authService;
});

尝试了很多事情,但到目前为止没有运气,请提出一个最好的方法,我已经尝试了 ui-routes 中的 resolve 方法,但没有奏效。

提前致谢。

最佳答案

您当前的实现将不起作用,因为 Data.get() 函数返回一个 Promise,因此是异步的。因此,路由更改将继续进行,而无需等到您的身份验证服务返回任何值。

要解决您的问题,您应该以特定方式处理此异步逻辑:

app.run(function ($rootScope, $location, $state, Data, AuthService) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
/**
* If the user is heading towards a state that requires
* authentication, assume that they are not authenticated,
* and stop them! Otherwise, let them through...
*/
if (toState.authenticate) {
event.preventDefault();

if (toState.name !== fromState.name) {
// Now check whether or not they are authenticated
AuthService.isAuthenticated().then(function () {
// Yes! They're authenticated, continue
$state.go(toState.name, toParams);
}, function () {
// Nope, this user cannot view this page
alert('You cannot view this page!');
});
}
} else {
return;
}
});
}

Edit: I have added a check statement toState.name !== fromState.name to break any redirect loops that may then cause endless calls to the authentication service. This was in response to a comment made by the original poster of the issue.

The trick is to prevent the route transition, by default. You are then able to perform as much asynchronous logic as you wish before the user is permitted to move any further on.

I would recommend adding a spinner, or a loading window, to alert the user to the fact that you are performing this authentication check. It may also be wise to prevent any further user actions on the page, but that's entirely up to you.

请注意,函数 AuthService.isAuthenticated() 现在返回一个 Promise,您必须对您的身份验证服务进行微小的更改才能实现此目的。像这样简单地包装您当前的逻辑:

app.factory('AuthService', function ($http, Data, $rootScope, $q) {
var authService = {};

authService.isAuthenticated = function () {
return $q(function (resolve, reject) {
Data.get('index.php/api/authentication/is_login').then(function (results) {
if (results.uid) {
$rootScope.authenticated = true;
$rootScope.uid = results.uid;
$rootScope.name = results.name;
$rootScope.email = results.email;

// Great, the user is authenticated, resolve the Promise
resolve(results.uid);
} else {
// The user does not appear to be authenticated, reject the Promise
reject();
}
});
});
};

return authService;
});

我希望这能解决您的问题,Promises 可能会让人痛苦,但它们也可以成为一个非常强大的工具。 GitHub 上有一个很好的话题讨论了围绕这个问题的许多潜在解决方案,可以在这里找到:https://github.com/angular-ui/ui-router/issues/1399 .


关于php - $stateChangeStart 在从 Rest API 获取数据之前运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37045474/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com