控制与服务和控制器的操作顺序(Controlling order of operations wit

2019-10-21 04:19发布

我有两个服务 - 一个存储用户的细节和对方打个电话来获取这些细节:

整个应用程序所使用userService存储用户的信息(在控制器,服务等即注入)

function userService($log) {        
    var id = '';
    var username = '';
    var isAuthenticated = false;

    var service = {
        id: id,            
        username: username,
        isAuthenticated: isAuthenticated
    };

    return service;
}

authService使用(希望只是一次)来检索从Web API控制器用户详细信息:

function authService($log, $http, userService) {
    $log.info(serviceId + ': Inside authService method');

    var service = {
        getUserDetails: getUserDetails
    };

    return service;

    function getUserDetails() {
        $log.info(serviceId + ': Inside getUserDetails method');

        return $http.get('api/authentication', { cache: true });
    }
}

最初,我曾在像这样一个.RUN块调用authService火:

.run(['$log', 'authService', 'userService', function ($log, authService, userService) {

    authService.getUserDetails()
        .then(querySucceeded);

    function querySucceeded(result) {
        userService.id = result.data.Id;
        userService.username = result.data.username;
    }
}]);

但问题是,getUserDetails,返回的承诺并没有解决,直到将我开除控制器后,因此,太晚了我。 用户数据还没有准备好。

然后我看着在$ stateProvider(对于UI的路由器)的决心选项:

.state('dashboard', {
                url: '/dashboard',
                views: {
                    header: {
                        templateUrl: 'app/partials/dashboard/header.template.html',
                        controller: 'DashboardHeaderController',
                        controllerAs: 'dashboardHeaderVM',
                        resolve: {
                            user: function (authService) {
                                return authService.getUserDetails();
                            }
                        }
                    }
                }
            })

假设是认为不会被渲染,直到解决部分的承诺是,好了,解决了。 这似乎很好地工作。

这里的控制器,我使用返回的用户属性(的相关部分):

function DashboardHeaderController($log, user) {
    var vm = this;

    // Bindable members        
    vm.firstName = user.data.firstName;
}

不过,我有两条路线(更多的惊喜),并且用户可以浏览到任何一个。 我需要有对authService每个州部分下决心财产? 我想火调用authService.getUserDetails只有一次,无论哪个路线服务,可将其之后的任何路线,控制器等。

有没有更好的(最佳实践)的方式来做到这一点?

Answer 1:

不知道更好或最佳实践,但这里是一个plunker用我的方式。

问题的关键是将resolve到一些家长根状态。 一个谁是应用程序中所有国家的祖先:

$stateProvider
  .state('root', {
    abstract : true,
    // see controller def below
    controller : 'RootCtrl',
    // this is template, discussed below - very important
    template: '<div ui-view></div>',
    // resolve used only once, but for available for all child states
    resolve: {
      user: function (authService) {
          return authService.getUserDetails();
      }
    }
  }) 

这是解决根的状态。 有决心的唯一国家。 下面是它的第一个孩子的例子(其他是类似这样定义方式:

$stateProvider
    .state('index', {
        url: '/',
        parent : 'root',
        ...

这种方法将工作开箱。 我只是想提一提的是,如果'RootCtrl'是这样定义的:

.controller('RootCtrl', function($scope,user){
  $scope.user = user;
})

我们应该明白与UI路由器继承。 看到:

  • 通过查看层次只有继承范围

小举:

请记住,如果你的国家的意见是嵌套作用域属性只继承下来的状态链。 作用域属性的继承 无关 ,与你的国家的嵌套一切 与你的意见 (模板) 的嵌套

这是完全有可能的,你嵌套状态,其模板填充在站点内的各种非嵌套位置UI的意见。 在这种情况下,你不能指望子女国的意见中访问的父状态视图的范围变量...

更多的解释可能在本作中找到Q&A

那么,这是什么意思?

我们的根视图可以通过解析的东西变成唯一的孩子的状态-如果他们的观点是嵌套的。

例如, $scope.user将儿童州/视图/ $范围被继承,只有当他们被嵌套这样

.state('index', {
    url: '/',
    parent : 'root',
    views: { 
      '' : { // the root view and its scope is now the ancestor
             // so $scope.user is available in every child view
        templateUrl: 'layout.html',
        controller: 'IndexCtrl'
      },
      'top@index' : { templateUrl: 'tpl.top.html',},
      'left@index' : { templateUrl: 'tpl.left.html',},
      'main@index' : { templateUrl: 'tpl.main.html',},
    },

检查它在这里



Answer 2:

如果我理解正确,你想要的页面加载,你会收到任何控制器或服务请求其用户信息。

我在当前项目中也有类似的任务。

为了解决我手动请求当前用户信息的问题,应用bootstapping之前和它存储在localStorage

然后应用自举的所有控制器后/服务有accesss当前用户信息。

提示:获取用户信息之前,应用程序引导你仍然可以通过手动注射使用它$ http服务:

angular.injector(['ng']).get('$http');


文章来源: Controlling order of operations with services and controllers