overexchange
overexchange

Reputation: 1

Angularjs - Controller inheritance Vs Scope inheritance

Below is the code using scope inheritance,

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title> Controller inheritance</title>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
        <script type="text/javascript">
            var sample = angular.module("sample", []);

            function ParentController(){
                this.Name = "Jag";
            }

            sample.controller("emp", ParentController);

            function ChildController(){
                this.Sal = 3500;
                this.Dept = "Sales";
            }

            sample.controller("empDetails", ChildController);
        </script>
    </head>s
    <body ng-app="sample">
        <div ng-controller="emp as o1">
            Employee details of <strong>{{o1.Name}}</strong>:
            <div ng-controller="empDetails as o2">
                <strong>{{o1.Name}}</strong> earns {{o2.Sal}} and works in {{o2.Dept}} department.
            </div>  
        </div>

    </body>
</html>

where nested scope of controller instanceo2 has to refer Name as o1.Name.

Below is the code for controller inheritance,

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title> Scope inheritance</title>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
        <script type="text/javascript">
            var sample = angular.module("sample", []);

            function ParentController(){
                this.Name = "Jag";
            }
            sample.controller("emp", ParentController);

            function ChildController(){
                ParentController.call(this);
                this.Sal = 3500;
                this.Dept = "Sales";
            }
            ChildController.prototype = Object.create(ParentController.prototype);
            sample.controller("empDetails", ChildController);
        </script>
    </head>
    <body ng-app="sample">
        <div ng-controller="emp as o1">
            Employee details of <strong>{{o1.Name}}</strong>:
        </div>
        <div ng-controller="empDetails as o2">
                <strong>{{o2.Name}}</strong> earns {{o2.Sal}} and works in {{o2.Dept}} department.
        </div>

    </body>
</html>

where scope of o2 is not nested.

To design inheritance hierarchy, Which approach does AngularJS recommend ?

Note: Terminology Controller inheritance is not a standard term.

Upvotes: 2

Views: 104

Answers (2)

mrahhal
mrahhal

Reputation: 3497

I wouldn't know what AngularJS recommends, but here are my thoughts.

First of all, I've never considered controller inheritance before. But now that I've seen it I can spot some potential nuisances at first sight.

  1. In this very case ParentController doesn't have dependencies so things play out nicely. But consider that later you needed to add a certain dependency (a service) to it, you'll have to remember to ask for that service in ChildController and then pass it to ParentController by hand. This is a big annoyance if you ask me.

  2. If we look at the html, the first way (normal scope inheritance) makes it obvious that ChildController indeed needs ParentController. The second case makes things harder to see, if I'm looking at the html I see no relation whatsoever between both controllers.

So for me, scope inheritance (which is actually the default way of doing things) beats controller inheritance in every way.

I believe the AngularJS team themselves haven't considered controller inheritance (but don't hold me for that), so better stick to the verifiable way of doing things.

Upvotes: 3

Renan Ferreira
Renan Ferreira

Reputation: 2150

This is not an answer to which approach is better. I think that, if you want to share some logic or data between two controller, you should use a Service for it. They were intended to be Singletons that you can inject in multiple controllers.

You will see lots of answer showing you how to make controller inheritance, but, using it will only lead you to big troubles (personal opinion, and already stated by mrahall). Why not use a really good mechanism that AngularJS provides you, to make you controller skin and elegant?

Just to show an example:

https://jsfiddle.net/relferreira/2b5amcya/

JS:

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

angular.module('app')
    .controller('MainController', mainController);

mainController.$inject = ['UserService'];

function mainController(UserService){

    var vm = this;
    vm.name = UserService.getName();

}

angular.module('app')
    .controller('DetailController', detailController);

detailController.$inject = ['UserService'];

function detailController(UserService){

    var vm = this;
    vm.name = UserService.getName();
    vm.other = 'test';

}

angular.module('app')
    .factory('UserService', userService);

function userService(){
    var name = 'Renan'; 
  return{
    getName: getName
  }

  function getName(){
    return name;
  }
}

HTML:

<div data-ng-app="app">

  <div data-ng-controller="MainController as mainVm">
    {{mainVm.name}}
  </div>

  <div data-ng-controller="DetailController as detailVm">
    {{detailVm.name}}
    {{detailVm.other}}
  </div>

</div>

Upvotes: 1

Related Questions