1

I have defined my UI-Router states like this:

$stateProvider.state('contact', {
        url: '/contactDemo',
        views: {
            'main': {
                controller: 'contactMainController',
                templateUrl: 'templates/contact.tpl.html'
            }
        }
    }).state('contact.details', {
        abstract: true,
        controller: 'contactDetailsController',
        templateUrl: 'templates/contact.details.tpl.html'
    }).state('contact.details.add', {
        url: '/add'
    }).state('contact.details.filter', {
        url: '/filter/{filterId}'
    }).state('contact.details.filter.record', {
        url: '/record/{recordId}',
        resolve: {
            record: ['$stateParams', 'Restangular', function($stateParams, Restangular) {
                return Restangular.one('records', $stateParams.recordId).get();
            }]
        }
    }).state('contact.details.filter.record.edit', {
        url: '/edit'
    });

Now I would like to inject my resolved record into contactDetailsController. If I do so, I get an Unknown provider error. I can't move the resolve into the abstract state, because from there I can't access the id inside $stateParams.

If I move the controller property down into the child state, my controller is never invoked.

Does anybody know how I can get the resolved property injected into the controller of an abstract parent state?

muenchdo
  • 2,161
  • 1
  • 17
  • 30

1 Answers1

1

As documented here, resolve could be inherited. NOT injected from child to parent.

Inherited Resolved Dependencies

New in version 0.2.0

Child states will inherit resolved dependencies from parent state(s), which they can overwrite. You can then inject resolved dependencies into the controllers and resolve functions of child states.

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

Simply solution where:

  1. $stateParam is defined in the child
  2. the resolve dependent on it should be injected into parent

cannot work - because one parent will be shared for many children.

Parent will stay while the children's params will differ..

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • But how do I inject something into the child state's controller (which is the same as the **abstract** parent state's controller)? – muenchdo Feb 17 '15 at 14:34
  • 1
    Very important thing to know is: Parent and Child controllers ARE NEVER the SAME. NEVER. Their types (definitions) could be, but they are different instances in runtime. So, you should rather introduce special controller for the child state - with resolver. That will simplify thinkging about states at all... – Radim Köhler Feb 17 '15 at 14:35
  • I was under the impression, that, because the parent state is abstract, there will only be one instance of the controller existent at runtime. Could you clarify, please? It is clear that I don't have one of my `detailsController`s as the child of another `detailsController`. – muenchdo Feb 17 '15 at 14:44
  • 1
    EVERY view has its one controller. Even implicit... They are (controllers per view) independent instances. So your child state should have template: xxx and controller: yyy defined. These will be injected into parents ui-view="". Check the basic examples about UI-Router – Radim Köhler Feb 17 '15 at 14:50
  • In [this answer](http://stackoverflow.com/a/20581135/1679310) are links to the most important resources, which you should observer, read carefully. Mostly the state.js link is what helped me to understand how to use UI-Router – Radim Köhler Feb 17 '15 at 15:00
  • Thanks, I'll have a look. – muenchdo Feb 17 '15 at 15:09