Spencer Spencer - 4 months ago 21
AngularJS Question

Child controller not inheriting from parent controller

I've been having a lot of trouble with understanding scope inheritance and I've tried my best to pass data objects from a parent controller into the child controller, but I can't seem to get things to work. Can someone explain why this isn't functioning? Thank you!

EDIT: I didn't specify this earlier, but it's a project requirement to use the John Papa style guide, so I can't solve this problem by using

$scope
in either of the controllers.

UPDATE: It seems I misunderstood the purpose of using
this
... based on help from posters below, I now understand that certain actions require the use of
$scope
and John Papa's style guide simply asks developers to use
this
when appropriate to avoid scope conflicts, not as a replacement for scope

JS

//parent.controller.js
(function () {
'use strict';

angular
.module('app')
.controller('ParentController', ParentController);

ParentController.$inject = ['$scope'];

function ParentController($scope) {
var vm = this;
console.log(this);
vm.test = {};
vm.test.label = "This is being set in the parent controller.";
}
})();

//child.controller.js
(function () {
'use strict';

angular
.module('app')
.controller('ChildController', ChildController);

ChildController.$inject = ['$scope'];

function ChildController($scope) {
var vm = this;
vm.test = vm.test;
}
})();


HTML

<div ng-controller="ParentController as vm">
<div>PARENT: {{vm.test.label}}</div>
<div ng-controller="ChildController as vm">
<div>CHILD: {{vm.test.label}}</div>
</div>
</div>


RESULT

PARENT: 'This is being set in the parent controller.'
CHILD:

Answer

Issue is: vm is also the part of the $scope itself. So you can not have same this instance for Parent & Child controller. Otherwise you will be facing issues while using them. If you want to isolate this instance for Parent & Child then give different names. Since vm is also the part of the controller so if you want to access Parent's vm inside Child controller then you will have to do $scope.vm

Working code as per your requirement is attached below:

Controller
---------
(function () {
                'use strict';

    angular
        .module('app', [])
        .controller('ParentController', ParentController);

    ParentController.$inject = ['$scope'];

    function ParentController($scope) {
        var vm = this;
        console.log(this);
        vm.test = {};
        vm.test.label = "This is being set in the parent controller.";
    }
})();

(function () {
    'use strict';

    angular
        .module('app')
        .controller('ChildController', ChildController);

    ChildController.$inject = ['$scope'];

    function ChildController($scope) {
        var childVm = this;
        childVm.test = $scope.vm.test;
    }
})();


HTML
---

<div ng-app="app">
            <div ng-controller="ParentController as vm">
                <div>PARENT: {{vm.test.label}}</div>
                <div ng-controller="ChildController as childVm">
                    <div>CHILD: {{childVm.test.label}}</div>
                </div>
            </div>
        </div>

Cheers!