What's the Recommended Way to Extend Angularjs Controllers

What's the recommended way to extend AngularJS controllers?

Perhaps you don't extend a controller but it is possible to extend a controller or make a single controller a mixin of multiple controllers.

module.controller('CtrlImplAdvanced', ['$scope', '$controller', function ($scope, $controller) {
// Initialize the super class and extend it.
angular.extend(this, $controller('CtrlImpl', {$scope: $scope}));
… Additional extensions to create a mixin.
}]);

When the parent controller is created the logic contained within it is also executed.
See $controller() for for more information about but only the $scope value needs to be passed. All other values will be injected normally.

@mwarren, your concern is taken care of auto-magically by Angular dependency injection. All you need is to inject $scope, although you could override the other injected values if desired.
Take the following example:

(function(angular) {
var module = angular.module('stackoverflow.example',[]);
module.controller('simpleController', function($scope, $document) { this.getOrigin = function() { return $document[0].location.origin; }; });
module.controller('complexController', function($scope, $controller) { angular.extend(this, $controller('simpleController', {$scope: $scope})); });
})(angular);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.js"></script>
<div ng-app="stackoverflow.example"> <div ng-controller="complexController as C"> <span><b>Origin from Controller:</b> {{C.getOrigin()}}</span> </div></div>

Angular.js best practice - extending controllers, overriding controller defaults

After half a year I think I understand completely what's going on.
As it is pointed out in a comment to this post, the simplest answer is services.

In the most optimal case, all your scope variables are values gathered from a factory/service. Still, you might want to use the exact same controller with one extra function: $scope.someFunction(){}, and keep the rest. In this case, you do have a 'thin' controller logic, which is the desirable controller design - but may still end up a hundred or more lines of code. You don't want that being duplicated in an other controller, just because you need some extra controller logic (like $scope.someFunction() )

What do you do then?

The answer is this:

  1. Make sure that you did everything in order to solve the situation with factories
  2. if you are abolutely certain you did, go for the controller injection:

    .controller('childController', function ($scope, $controller) {
    'use strict';
    $controller('parentController', {$scope: $scope});
    $scope.someFunction=function(){}
    })

It's that simple. -- again, usually, things can be solved with factories..

Hope you find this useful ;)

Extending a controller's specific functions

Extending my comment:

 app.controller('parentCtrl', function($scope,$rootscope) {

$rootscope.myPerent = function () {
//your code
}

});

app.controller('childCtrl', function($scope,$rootscope) {

$scope.ourPerent = function () {
$rootscope.myPerent();
}

});

What's the recommended way to extend AngularJS controllers?

Perhaps you don't extend a controller but it is possible to extend a controller or make a single controller a mixin of multiple controllers.

module.controller('CtrlImplAdvanced', ['$scope', '$controller', function ($scope, $controller) {
// Initialize the super class and extend it.
angular.extend(this, $controller('CtrlImpl', {$scope: $scope}));
… Additional extensions to create a mixin.
}]);

When the parent controller is created the logic contained within it is also executed.
See $controller() for for more information about but only the $scope value needs to be passed. All other values will be injected normally.

@mwarren, your concern is taken care of auto-magically by Angular dependency injection. All you need is to inject $scope, although you could override the other injected values if desired.
Take the following example:

(function(angular) {
var module = angular.module('stackoverflow.example',[]);
module.controller('simpleController', function($scope, $document) { this.getOrigin = function() { return $document[0].location.origin; }; });
module.controller('complexController', function($scope, $controller) { angular.extend(this, $controller('simpleController', {$scope: $scope})); });
})(angular);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.js"></script>
<div ng-app="stackoverflow.example"> <div ng-controller="complexController as C"> <span><b>Origin from Controller:</b> {{C.getOrigin()}}</span> </div></div>

Best way to extend third party libraries in AngularJs

One option is to decorate the directive. Decoration looks something like:

angular.module('app', ['ui.bootstrap']).
config(function($provide){
// Inject provide into the config of your app
$provide.decorator('datepickerDirective', function($delegate){

// the directive is the first element of $delegate
var datepicker = $delegate[0];

// Add whatever you want to the scope:
angular.extend(datepicker.scope, {
customAttribute: '@',
customMethod: '@'
});

// Might want to grab a reference to the old link incase
// you want to use the default behavior.
var oldLink = datepicker.link;

datepicker.link = function(scope, element, attrs){
// here you can write your new link function
oldLink(scope, element, attrs);
};

return $delegate;
});
});


Related Topics



Leave a reply



Submit