0

I am trying to achieve Controller inheritance in Angularjs and followed several articles and examples and couldnot make it work.

I have common functionality across 2 controllers and i have created BaseController for common functionalities and ChildControllers extended this controller.

HTMl file

 <div ng-controller="ChildCtrl1"> 
  <div>Gettting absolute url from parent: <strong>{{commonVar}}</strong></div>
  <button  class="btn btn-primary pull-left" ng-click="scopeChildMethod1 ()">OK</button>
</div>

BaseCtrl.js

var dependencies = []; 
define( dependencies, function()
{   
  function BaseCtrl($scope,$location) {
        $scope.commonVar = 42;
        $scope.commonMethod1 = function () {
            alert('test');
          };
  };
    BaseCtrl.prototype.commonMethod2 = function () {
      alert('test2');
    };

  return BaseCtrl;

 });

ChidlCtrl1.js

var dependencies = [ './module','./BaseCtrl'];
define(dependencies, function (module,BaseCtrl) {
  return module.controller('ChildCtrl1', function ($scope,$location){
    var  ChildCtrl1=function($scope, $location) {
        BaseCtrl.call(this, $scope, $location);
        $scope.scopeChildMethod1 = function () {
            alert('test');
          };

   }
      ChildCtrl1.prototype = new BaseCtrl($scope, $location);

      ChildCtrl1.prototype.childMethod2 = function () {
        alert('test');
      };

     return ChildCtrl1;
});

 });

I see that child scope method is not triggered on button click??where as i can trigger the scope method in BaseController.I am not sure whats wrong in the above code as in why i cannot trigger child methods???

Any help will be appreciated.

1 Answer 1

3

module.controller takes in a function for the controller as the second argument. You just need to change how you're calling module.controller, like so:

var ChildCtrl1 = function ($scope, $location) {
    BaseCtrl.call(this, $scope, $location);
    $scope.scopeChildMethod1 = function () {
        alert('test');
    };
    $scope.childMethod2 = ChildCtrl.childMethod2;

};

ChildCtrl1.prototype =  Object.create(BaseCtrl.prototype);

ChildCtrl1.prototype.childMethod2 = function () {
    alert('test');
};


module.controller('ChildCtrl1', ChildCtrl1);

Note however that this line:

ChildCtrl1.prototype = new BaseCtrl($scope, $location);

was changed to this:

ChildCtrl1.prototype = Object.create(BaseCtrl.prototype);

Unfortunately the original line won't work as $scope and $location don't exist at this point, but it's fine as you're calling BaseCtrl.call(this, $scope, $location); in the ChildCtrl constructor anyway.

IE8

If you need this to work in IE8, you can add a polyfill:

if (typeof Object.create != 'function') {
  Object.create = (function() {
    var Object = function() {};
    return function (prototype) {
      if (arguments.length > 1) {
        throw Error('Second argument not supported');
      }
      if (typeof prototype != 'object') {
        throw TypeError('Argument must be an object');
      }
      Object.prototype = prototype;
      var result = new Object();
      Object.prototype = null;
      return result;
    };
  })();
}
Sign up to request clarification or add additional context in comments.

8 Comments

Isn't it better to do ChildCtrl1.prototype = Object.create(BaseCtrl.prototype); A Child is a Parent but a Parent is not always a Child (like a Dog is an Animal but an Animal isn't always a Dog as it can be a Shark too).
I need to make this work in IE 8,so I can only use new operator.
by doing the above change to controller ,i can now trigger child and Base scope methods but how to trigger the child and base prototype methods from html.I have replaced the button click with child & base prototype methods and didn't work <button class="btn btn-primary pull-left" ng-click="childMethod2 ()">OK</button>
Also i have an another question with controller inheritance in angularjs,all i have seen in examples are pointing to abstract constructor function called from child controller but haven't seen the controller extending other controller??whereas factory can extend other factory??
@EnugulaS For your first question, are you making sure you're setting the childMethod2 to your scope? Just have as a function on your controller will not work. Unless you're using the as syntax. As for your second question, can you clarify a bit, what exactly do you mean by extending?
|

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.