2

I'm using AngularJs UI-Router for my app, but I'm with a problem where the parent's controller isn't initiated.

This is my state structure:

.state('main', { abstract: true, controller: 'MainController', controllerAs: 'vm', resolve: { config: function($timeout){ return $timeout(function() { return console.log('loaded') }, 1000); } } }) .state('home', { parent: 'main', url: '/Home', views: { 'content@': { templateUrl: 'view/home.html' } } }) .state('contact', { parent: 'main', url: '/Contact', views: { 'content@': { templateUrl: 'view/contact.html', } } }) 

The template home.html and contact.html are displaying on the view just fine. But inside the MainController I have just a console.log but it doesn't appear on the console.

If I make some changes, I can make it work. This is the working example:

.state('main', { abstract: true, views: { 'main': { template: '<div ui-view="content"></div>', controller: 'MainController', controllerAs: 'vm' } } [...code...] .state('home', { parent: 'main', url: '/Home', views: { 'content': { [...code...] 

This way, everything works as expected, The view appear and the console from the controller also appear.

But it doesn't seem "right" because I need to create a template just to hold the child states.

Is there a way to make it work with the first option?

2
  • i've had problems using controllerAs try to use controller: MainController as vm Commented Sep 1, 2016 at 2:59
  • @PauloGaldoSandoval Since i was using the controller just for tests and to print a console, i tired to use it just as controller: 'MainController', without the controllerAs, but got the same results. Commented Sep 1, 2016 at 3:11

1 Answer 1

1

Well, to answer:

... Is there a way to make it work with the first option?

Have to say: NO. The point is:

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).

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.

So, what happened is - the child state views: {} definition:

.state('contact', { parent: 'main', views: { 'content@': { ... 

... forced child to skip parent view. Not parent state. It skips a parent view. There is no parent view, from which it could inherit the $scope.

The view of a child state 'contact', is injected directly into root (index.html) ui-view="content", it will not trigger parent view...

So, use the second approach, which is absolutely correct, to achieve what is exepected

Check also these for farther details and working examples:

Sign up to request clarification or add additional context in comments.

1 Comment

I knew about the inheritance hierarchy, but I tought it was only applied to the resolve data, not to all views and controllers. Thanks for the great answer explaning what is actually happening!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.