5

I use angular 1.5 to develop my application and I am using .component(). I have three components and their controllers, all of which are quite similar. How can I extend the controller from comp1 to use it with comp2?

Each component in a separate js file:

comp1.js comp2.js comp3.js

4
  • Is this what you are looking for? Commented Jun 28, 2016 at 11:07
  • unfortunately this answer spoke about controller and not .component() Commented Jun 28, 2016 at 11:16
  • This has nothing to do with the component. In Angular 1.5 components are just a simpler way to write directives. The components/directive uses a controller the same way as you can annotate and html-tag with ng-controller. Commented Jun 28, 2016 at 11:19
  • What did you decide? One suggestion, though it requires a major head rethread, if you're still on AngularJS in 2020: Consider moving your codebase to TypeScript, which helps to abstract that extension process for you. Commented Oct 2, 2020 at 15:29

2 Answers 2

1

You can extend component controllers from each other as well. Use the following approach:

Parent component (to extend from):

/**
 * Module definition and dependencies
 */
angular.module('App.Parent', [])

/**
 * Component
 */
.component('parent', {
  templateUrl: 'parent.html',
  controller: 'ParentCtrl',
})

/**
 * Controller
 */
.controller('ParentCtrl', function($parentDep) {

  //Get controller
  const $ctrl = this;

  /**
   * On init
   */
  this.$onInit = function() {

    //Do stuff
    this.something = true;
  };
});

Child component (the one extending):

/**
 * Module definition and dependencies
 */
angular.module('App.Child', [])

/**
 * Component
 */
.component('child', {
  templateUrl: 'child.html',
  controller: 'ChildCtrl',
})

/**
 * Controller
 */
.controller('ChildCtrl', function($controller, $parentDep) {

  //Get controllers
  const $ctrl = this;
  const $base = $controller('ParentCtrl', {$parentDep});

  //Extend
  angular.extend($ctrl, $base);

  /**
   * On init
   */
  this.$onInit = function() {

    //Call parent init
    $base.$onInit.call(this);

    //Do other stuff
    this.somethingElse = true;
  };
});

You can define new method in the child controller, overwrite existing methods, call the parent methods, etc. Works really well.

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

Comments

1

I may suggest that you simply use services to share and compose components. You can then skip the complexities of worrying about .extend(), $controller, etc.

  angular
    .module('app')
    .factory('component.utils', function() {
       return {
         sharedProp: 'foo',
         sharedMethod: function() { return 'bar' }
       }
    })
    // components can all easily use functionality 
    // provided by one (or more) services, w/o 
    // needing a complicated inheritance model.
    .component('foo', {
      templateUrl: 'foo.html',
      controller: [
        'component.utils',
        function(utils) {
          this.$onInit = function() {
            this.prop = utils.sharedProp;
            utils.sharedMethod();
            // now do other foo things...
          }
        }
      ]
    })
    .component('bar', {
      templateUrl: 'foo.html',
      controller: [
        'component.utils',
        function(utils) {
          this.$onInit = function() {
            this.prop = utils.sharedProp;
            utils.sharedMethod();
            // now do other bar things...
          }
        }
      ]
    });

Inheritance has its place, but favoring composition over inheritance is usually the better solution. article.

Comments

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.