控制与服务和控制器的操作顺序 [英] Controlling order of operations with services and controllers

查看:307
本文介绍了控制与服务和控制器的操作顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个服务 - 一个用于存储用户的细节和对方拨打电话,以获取这些详细信息:

I have two services - one to store user details and the other to make a call to retrieve those details:

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火了:

Initially, I had the call to the authService fire in a .run block like so:

.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,返回的承诺并没有解决,直到我在我的控制器解雇之后,因此,太晚了我。用户数据还没有准备好。

But the problem was that the getUserDetails-returned promise did not resolve until after I my controllers fired and, thus, too late for me. The user data was not ready.

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

I then looked at the resolve option in the $stateProvider (for UI-Router):

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

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

The assumption is that the view won't be rendered until the promise in the resolve section is, well, resolved. That seems to work fine.

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

Here's the (relevant part of the) controller where I use the returned user property:

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

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

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

However, I have two routes (more to come) and a user can navigate to either one. Do I need to have a resolve property in each state section for the authService? I want to fire the call to authService.getUserDetails just once no matter which route is served and have it available after that for any route, controller, etc.

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

Is there a better (best practice) way to do this?

推荐答案

不知道有关好或最好的做法,但这里是一个的 plunker用我的方式

Not sure about better or best practice, but here is a plunker with my way.

问题的关键是将决心进入一些的的根状态。一个谁是所有国家的祖先中的应用:

The point is to move resolve into some parent root state. The one who is ancestor of all states in the application:

$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();
      }
    }
  }) 

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

This is a root state with resolve. The only state with resolve. Here is an example of its first child (any other would be defined similar way:

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

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

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

我们应该明白与UI路由器继承。参见:

we should understand the UI-Router inheritance. See:

  • Scope Inheritance by View Hierarchy Only

小举:

记住,如果你的国家的意见是嵌套作用域属性只继承下来的状态链。范围的继承性能无关与你的国家的嵌套所有做的与你的看法嵌套(模板)。

Keep in mind that scope properties only inherit down the state chain if the views of your states are nested. Inheritance of scope properties has nothing to do with the nesting of your states and everything to do with the nesting of your views (templates).

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

It is entirely possible that you have nested states whose templates populate ui-views at various non-nested locations within your site. In this scenario you cannot expect to access the scope variables of parent state views within the views of children states...

更多的解释可以在这个 Q&放大器可以找到;一个

More explanation could be found in this Q & A

那么,这是什么意思?

So, what does it mean?

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

Our root view can pass the resolved stuff into child state only - if their views are nested.

例如,在 $ scope.user 将在孩子的状态/视图/ $范围被继承,只有当他们被嵌套这样的

For example, the $scope.user will be inherited in child states/views/$scopes only if they are nested like this

.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',},
    },

检查一下这里

这篇关于控制与服务和控制器的操作顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆