Shannon Hochkins
Shannon Hochkins

Reputation: 12176

Access parent controller from sub ui-view component

I can't seem to find an answer on this one, I've tried using require, but no luck It can't find the 'settings' parent from the component definition.

I want all of the 'child' routes to have access to all the 'settings' methods so I can re-use methods across multiple states.

How can I access methods on the 'settings' component controller, from a nested ui-view component?

index.html

<ui-view></ui-view>

app.js

$stateProvider.register('settings', {
    abstract : true,
    component: 'settings',
    url : '/settings'
});
$stateProvider.register('settings.user', {
    component: 'settingsUser',
    url : '/:user',
});

angular.module('app', [])
    .component('settings', {
        template : `<ui-view></ui-view>`,
        controller : class Settings {
            constructor($state) {
                this.test = () => console.log('test');
                $state.go('settings.user');
            }

        }
    })
    .component('settingsUser', {
         controller : class SettingsUser {
             constructor() {
                 // want to access parent controller methods
             }
         }
    });

Upvotes: 0

Views: 505

Answers (2)

Shannon Hochkins
Shannon Hochkins

Reputation: 12176

The answer was actually quite simple, I just didn't expect it to work with routes, with the child view you can simply require the parent component through the require block. This exposes the controller of the required component in the $onInit life cycle phase in the child view's controller.

$stateProvider.register('settings', {
    abstract : true,
    component: 'settings',
    url : '/settings'
});
$stateProvider.register('settings.user', {
    component: 'settingsUser',
    url : '/:user',
});

angular.module('app', [])
    .component('settings', {
        template : `<ui-view></ui-view>`,
        controller : class Settings {
            constructor($state) {
                this.test = () => console.log('test');
                $state.go('settings.user');
            }

        }
    })
    .component('settingsUser', {
         require : {
             $settings : '^settings'
         },
         controller : class SettingsUser {
             constructor() {
                 // want to access parent controller methods
             }
             $onInit() {
                 this.$settings.test()
             }
         }
    });

Upvotes: 1

ferhado
ferhado

Reputation: 2604

You can access it using a $rootScope instead $scope for what you access want. in ths example test1 is a $rootscope but test2 is a $scope, in controller Ctrl2 we change the test1 and it will be changed in Ctrl1 see Example:

var app = angular.module('myApp', []);
app.controller('Ctrl1', function($scope,$rootScope) {
    $rootScope.test1 = "topController";
    $scope.test2 = "topController2";
})
.controller('Ctrl2', function($scope,$rootScope) {
    $rootScope.test1 = "mainController";
    $scope.test2 = "mainController2";
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" >
  <div ng-controller="Ctrl1">
  {{test1}} {{test2}}
  </div>
  <div ng-controller="Ctrl2">
  {{test1}} {{test2}}
  </div>
</div>

Upvotes: 0

Related Questions