1

I've got a problem that is getting into my nerves regarding some methods extending in an angular child controller. My primary goal is to inherit all the public /$scope/ variables and methods from the parent controller into the child one, but extend some specific functions with more logic. So this is what I have in general:

var app = angular.module("conrollersInheritance", []);

app.controller("parentController", [
    "$scope",
    function ($scope) {
        /* PRIVATE */
        var privateVar1 = "private variable 1";
        var privateVar2 = "private variable 2";

        // ...Some other private stuff here...

        /* PUBLIC */
        $scope.publicVar1 = "public variable 1";
        $scope.publicVar2 = "public variable 2";

        $scope.showVars = function () {
            console.log("PRIVATE: ", privateVar1, privateVar2);
            console.log("PUBLIC: ", $scope.publicVar1, $scope.publicVar2);
        };

        // ...Some other public stuff here...
    }
]);

app.controller("childController", [
    "$scope", "$controller",
    function ($scope, $controller) {
        $controller("parentController", { $scope: $scope });

        $scope.showVars = function () {
            alert("child scope");
            // ???Here I want to execute the inherited method from the `parentController`
        };
    }
]);

So basically, the childController inherits all the $scope data from the parentController which is fine, but I cannot seem to extend the functionality inherited, but always override it. I tried different approaches to solve the problem, because I saw from the Angular docs that the $controller service should return the instance / https://docs.angularjs.org/api/ng/service/$controller /, but in my case it always returns an empty contructor object. SO when I try to do something like this into the childController:

var parentController = $controller( "parentController", { $scope: $scope } );

I am always getting an emtpy object for the parentConroller variable and I cannot use anything inherited from there. Tried to use the viewmodel declaration inside the childController with something like this:

var vm = this;
$controller( "parentController", { vm: $scope } );
angular.extend( $scope, vm );

but also seems not to be the right decisions as it throws an error when trying to extend the scope and I cannot do anything like this as well:

$scope.showVars = function() {
    alert( "child scope" );
    vm.showVars();
};

So, I'm kind of stuck how can I do this. I read a lot of tutorials claiming that above methods should work, but it doesn't look like this in my case. So, any ideas? Thanks!

2
  • $scope.$parent.showVars()? Commented Jun 15, 2017 at 5:07
  • hmmm, haven't thought about that this could happen. I will check it up now... probably this will help me fix that thing. Commented Jun 15, 2017 at 8:06

1 Answer 1

1

Thanks to prototypical inheritance, your child controller inherits all parent's properties/methods from the $scope by default, if your controllers are nested.

You can nest controllers by either using ui-router and defining a child state

.state('route', {
    controller: 'ParentController',
    // the rest of the route config
})

.state('route.child', {
    controller: 'ChildController',
    // the rest of the route config
})

or by nesting them in the template

<div ng-controller="ParentController">
    <div ng-controller="ChildController">
        <!-- the rest of your template -->
    </div>
</div>

Then you can simply extend your ParentController method like this:

$scope.showVars = () => {
    $scope.$parent.showVars();
    // your other logic
};

That will create a a showVars method on your ChildController's $scope which will be used by default by your template instead of the one inherited fro mthe ParentController.

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

2 Comments

That looks great. I'm actually using the ui-router to create states, but for each state I am assigning either a custom controller or ParentController. And if I want to use any functionality from ParentController into the custom one, I use $controller provider to extend it's $scope. But then accessing the ParentController scope seems impossible, as $scope.$parent doesn't consist with it's methods and variables. Do I need to make changes on states and make all of them nested to a single main state that has the ParentController assigned?
I believe the best practice would be to assign one controller per state. If you have child state, its controller will automatically inherit everything from the controller of its parent state.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.