web-dev-qa-db-fra.com

Utilisation de $ scope dans la résolution du routeur ui

J'utilise la résolution de routeur ui afin d'obtenir des données d'un service.

Le problème est que je dois obtenir une valeur de la portée du parent $ afin d'appeler le service comme indiqué ci-dessous. 

resolve: {
              contactService: 'contactService',
              contacts: function ($scope, contactService) {
                  return contactService.getContacts($scope.parentCtrl.parentObjectId);
              }
          }

Je continue à recevoir Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!

Nous avons également tenté quelques tentatives désespérées, telles que l’ajout de la portée à l’objet de résolution, comme indiqué ci-dessous sans succès.

scope: $scope

Des idées?

14
Loukas Avramidis

C'est impossible, la portée n'a pas encore été initialisée, vous ne pouvez donc pas l'utiliser dans l'objet de résolution. Vous pouvez accéder à l'étendue dans le contrôleur après son initialisation. Le point essentiel de la résolution est qu'il exécute avant l'initialisation du contrôleur afin que vous puissiez injecter et accéder directement aux éléments résolus dans votre étendue.

Si vous devez passer une variable à l'état suivant, vous pouvez le faire en utilisant l'objet $stateParams qui est disponible pour être utilisé dans la résolution. Vous pouvez y ajouter des données lors du changement d'état, par exemple:

Dans votre modèle, si vous avez un objectId dans votre portée:

<a ui-sref="statename({'id': objectId})">Change states</a>

Ou dans votre contrôleur:

$scope.go('statename', {'id': $scope.objectId});

Vous pouvez ensuite récupérer cela dans votre résolution en utilisant le $stateParams:

resolve: {
    contactService: 'contactService',
    contacts: function ($stateParams, contactService) {
        return contactService.getContacts($stateParams.id);
    }
}
19
iH8

En guise d'alternative à la solution acceptée, qui nécessite un autre aller-retour sur le serveur pour la même ressource (si vous obtenez la valeur du serveur/api), vous pouvez $watch le parent du contrôleur enfant.

function ParentController($http) {
  var vm = this;
  $http.get(someResourceUrl).then(function(res) {
    vm.someResource = res.data;
  });
}

function ChildController($scope) {
  // wait untill the parent gets the value
  var unwatch = $scope.$watch('parent.someResource', function(newValue) {
    if (newValue) {
      // the parent has the value, init this controller
      init(newValue);
      // dispose of the watcher we no longer need
      unwatch();
    }
  });
  function init(someResource) {
    // ... do something
  }
}

function routerConfig($stateProvider) {
  $stateProvider
    .state('parent', {
      url: '/parent',
      controller: 'ParentController',
      controllerAs: 'parent',
      templateUrl: '...',
    })
    .state('parent.child', {
      url: '/child',
      controller: 'ChildController',
      controllerAs: 'child',
      templateUrl: '...',
    });
}
0
redben