it-swarm.com.de

Verwendung von $ scope bei der UI-Router-Auflösung

Ich verwende eine UI-Router-Auflösung, um Daten von einem Dienst zu erhalten.

Die Sache ist die, dass ich einen Wert aus dem übergeordneten $ scope erhalten muss, um den Dienst wie unten gezeigt aufzurufen. 

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

Ich bekomme immer Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!

Es wurden auch einige verzweifelte Versuche unternommen, z. B. das Auflösungsobjekt mit Gültigkeitsbereich zu versehen (siehe unten), jedoch ohne Erfolg.

scope: $scope

Irgendwelche Ideen?

14

Das ist unmöglich, der Gültigkeitsbereich wurde zu diesem Zeitpunkt noch nicht initialisiert, sodass Sie ihn nicht im Auflösungsobjekt verwenden können. Sie können auf den Bereich im Controller zugreifen, nachdem er initialisiert wurde. Der entscheidende Punkt bei der Auflösung ist, dass die Initialisierung mit before controller ausgeführt wird, sodass Sie die aufgelösten Elemente in Ihrem Bereich einfügen und direkt darauf zugreifen können.

Wenn Sie eine Variable an den nächsten Status übergeben müssen, können Sie dies tun, indem Sie das $stateParams-Objekt verwenden, das für die Auflösung verfügbar ist. Sie können Daten hinzufügen, wenn Sie den Status ändern, zB:

Wenn Sie in Ihrer Vorlage eine objectId in Ihrem Gültigkeitsbereich haben:

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

Oder in deinem Controller:

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

Sie können das dann in Ihrer Lösung abrufen, indem Sie den $stateParams verwenden:

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

Als Alternative zu der akzeptierten Lösung, die einen weiteren Roundtrip zum Server für dieselbe Ressource erfordert (wenn Sie den Wert vom Server/der API erhalten), können Sie den übergeordneten Controller vom untergeordneten Controller $watch.

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