AngularJS等待$ http请求

时间:2017-04-02 09:12:22

标签: javascript angularjs angular-ui-router

我有一个使用ui-router的AnuglarJS应用程序,我有一个http请求,告诉用户有关用户的信息,如登录状态,访问权限,语言,用户组,他可以访问的控制器等等。它还定义了一些控制器的行为,我的ui-router状态依赖它。

$today_date = date("d/m/y");
$from_date = 01/04/2017;
$to_date = 05/04/2017;

if(($today_date >= $from_date) && ($today_date <= $to_date))
{
  echo("ok");
}
else
{
  echo("Not ok");
}

现在我想延迟所有ui-router状态更改和延迟服务,如果可能的话。并且只允许在请求返回后在角度应用中发生任何事情。所以我可以将用户重定向到登录页面或加载适当的模板,或者根据收到的信息在应用程序中做我想做的任何事情。

我希望这适用于可能添加例外的多条路线。

所以我想实现的目标是延迟加载angular.js应用程序,等待http请求完成然后继续应用程序。

2 个答案:

答案 0 :(得分:1)

您可以使用$stateChangeStart提供的ui-router默认事件来实现此目的。它在任何路线改变之前被调用。您可以将这些内容放在主应用程序模块定义对象的run()部分。

/**
 * Before state change / page switch
 */
$rootScope.$on("$stateChangeStart", function (event, toState, toParams, fromState, fromParams, options) {

   //prevent default route change if user is not available in factory/service.
   if ((!UserService.userData || !UserService.userData.loggedIn) 
          && toState.name !== 'login') {

        event.preventDefault();

        $http.get("/user").then(function(response) {
            if (response.data.loggedIn) {
                UserService.userData = response.data.userData;
                if (toState.name !== fromState.name) {
                   $state.go(toState.name, toParams, options);
                }
            } else {
                $state.go('login');
            }
        });
   }
});

提示:为了检查登录会话状态,不在任何路由更改上触发HTTP-Request会好得多。您可以将会话状态存储到localStorage中,从而为您提供性能提升。在从后端的安全路由中获取数据的任何请求中检查此会话状态。如果会话不再处于活动状态,请在用户尝试访问此数据时重定向。

答案 1 :(得分:1)

每当我的应用程序依赖于预先加载的数据时,无论是用户详细信息,权限还是其他任何内容,我都会将所有应用程序路由嵌套在单个根路由下,并使用resolve选项。< / p>

例如,下面是一段代码,用于加载区域设置的用户设置,然后初始化我的本地化服务,该服务将继续翻译整个应用程序:

routeConfig.$inject = ['$stateProvider', '$urlRouterProvider'];
function routeConfig($stateProvider, $urlRouterProvider) {
    $urlRouterProvider
        .otherwise("/");

    $stateProvider
        .state('root', {
            url: '',
            abstract: true,
            template: '<div navbar></div><div ui-view class="container"></div>',
            resolve: {
                dependencies: globalAppDependencies
            }
        })
        .state('root.index', {
            url: '/',
            template: '<div main-page></div>'
        })
        .state('root.showcase', {
            url: '/showcase',
            template: '<div showcase-page></div>'
        });

    globalAppDependencies.$inject = ['userRepository', 'myLocalization'];
    function globalAppDependencies(userRepository, myLocalization) {
        return userRepository.login()
            .then(function (user) {
                return myLocalization.setLocale(user.locale);
            });
    }
}

注意: root路由模板除了html模板中的模板外,还包含ui-view。这是必需的,因为所有应用视图都嵌套在root下面。

我的应用模板如下所示:

<div ng-app="my-application">
    <div application-loader></div>
    <ui-view></ui-view>
</div>

在我们提取用户设置和本地化文件时,application-loader用于动画。