用于父状态的角度ui-router解析

时间:2015-02-16 03:10:59

标签: angularjs angular-ui-router

在我的父州,我有一个resolve。目前,我没有在任何子状态下注入 resolve 键。

我认为我的孩子状态不会等待这个决心/承诺得到解决。但是当我设置超时时,我可以看到我的孩子状态确实等待。

这是正确的行为吗?

.config(function ($stateProvider, $urlRouterProvider, STATES) {
    $stateProvider
        .state(STATES.ROOT, {
            abstract: true,
            template:'<div ui-view=""></div>',
            resolve: {                  
                UserService: 'UserService',
               userDetails: function(UserService){
                   return UserService.getUserProfile();
                }

            }
        })
        .state(STATES.BILLING, {
            url: '/bill/checkClientContext.html',
           templateUrl: 'bill/checkClientContext.html',
            controller: 'BillingController'
        })

UserService.js

'use strict';
angular.module('nabc.data')
    .service('UserService', ['AjaxService', '$timeout','$q', function(AjaxService, $timeout, $q) {
        var getUserProfile = function() {
            var promise = AjaxService.get('userProfile');

            var deferred = $q.defer();
            $timeout(function(response){
                deferred.resolve(response);
            }, 5000);
            return deferred.promise;


        };

        return {
            getUserProfile: getUserProfile
        };
    }]);

如您所见,BillingController未注入userDetails。但是当我在userService中设置超时时,我发现我的计费状态确实等待了。

2 个答案:

答案 0 :(得分:4)

答案可以在这里找到(让我引用几行和片段)

Inherited Resolved Dependencies

版本0.2.0中的新功能

  

子状态将从父状态继承已解析的依赖关系,它们可以覆盖它们。然后,您可以将已解析的依赖项注入控制器并解析子状态的功能。

$stateProvider.state('parent', {
      resolve:{
         resA:  function(){
            return {'value': 'A'};
         }
      },
      controller: function($scope, resA){
          $scope.resA = resA.value;
      }
   })
   .state('parent.child', {
      resolve:{
         resB: function(resA){
            return {'value': resA.value + 'B'};
         }
      },
      controller: function($scope, resA, resB){
          $scope.resA2 = resA.value;
          $scope.resB = resB.value;
      }

因此,正如我们在文档中看到的那样,父母的决心可以用于孩子。这实际上是理由,而我们必须等待解决 ...才能继续。

但我会说,这是预期的。更奇特的功能是:

  

如果子状态已定义resolve - 并且父级没有 - 那么很容易看到父视图呈现,并且只允许子视图等待。

这是(据我所知)计划在不久的将来作为一项功能......

EXTEND - 等待所有人继续是答案

得到答案:

  

所有结算 - 必须在当前状态声明,所有 父状态 - 必须等待才能继续与当前?即使当前的状态控制器不需要这些值中的任何一个吗?

请遵守以下代码: state.js

function resolveState(state, params, paramsAreFiltered, inherited, dst, options) {
  // Make a restricted $stateParams with only the parameters that apply to this state if
  // necessary. In addition to being available to the controller and onEnter/onExit callbacks,
  // we also need $stateParams to be available for any $injector calls we make during the
  // dependency resolution process.
  var $stateParams = (paramsAreFiltered) ? params : filterByKeys(state.params.$$keys(), params);
  var locals = { $stateParams: $stateParams };

  // Resolve 'global' dependencies for the state, i.e. those not specific to a view.
  // We're also including $stateParams in this; that way the parameters are restricted
  // to the set that should be visible to the state, and are independent of when we update
  // the global $state and $stateParams values.
  dst.resolve = $resolve.resolve(state.resolve, locals, dst.resolve, state);
  var promises = [dst.resolve.then(function (globals) {
    dst.globals = globals;
  })];
  if (inherited) promises.push(inherited);

  // Resolve template and dependencies for all views.
  forEach(state.views, function (view, name) {
    var injectables = (view.resolve && view.resolve !== state.resolve ? view.resolve : {});
    injectables.$template = [ function () {
      return $view.load(name, { view: view, locals: locals, params: $stateParams, notify: options.notify }) || '';
    }];

    promises.push($resolve.resolve(injectables, locals, dst.resolve, state).then(function (result) {
      // References to the controller (only instantiated at link time)
      if (isFunction(view.controllerProvider) || isArray(view.controllerProvider)) {
        var injectLocals = angular.extend({}, injectables, locals);
        result.$$controller = $injector.invoke(view.controllerProvider, null, injectLocals);
      } else {
        result.$$controller = view.controller;
      }
      // Provide access to the state itself for internal use
      result.$$state = state;
      result.$$controllerAs = view.controllerAs;
      dst[name] = result;
    }));
  });

  // Wait for all the promises and then return the activation object
  return $q.all(promises).then(function (values) {
    return dst;
  });
}

我决定在这里引用完整的方法,但最重要的部分是:声明 var promises = []; 。此数组稍后会扩展,并继续 promises.push($resolve.resolve(... 所需的所有结算,最后,直到所有内容都没有完成,没有结果 - return $q.all(promises) < / p>

答案 1 :(得分:1)

  1. 父控制器总是在子控制器之前加载(如果没有加载某些相邻的子状态之前)。
  2. 控制器需要等待其解析部分。
  3. 这是一个简短的例子,让我们说我们的父状态 P 有解决部分和两个子状态 C1 C2

    第一种情况 - 您从单独的状态导航到 P.C1 状态,或者只是在浏览器中点击相应的网址。订单如下:

    • 父亲执行的决议部分
    • 已加载父级控制器
    • 已加载儿童控制器

    第二种情况 - 您从 P.C1 导航到 P.C2 ,在这种情况下 P don&# 39; t需要加载,因此只加载 C2 控制器。