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:
- Make sure that you did everything in order to solve the situation with factories
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
Remove Items from Array with Splice in for Loop
How Does Garbage Collection Work in JavaScript
How to Destructure Object Properties with Key Names That Are Invalid Variable Names
Jquery Disable Form Submit on Enter
Document.All VS. Document.Getelementbyid
(1, Eval)('This') VS Eval('This') in JavaScript
Removeeventlistener on Anonymous Functions in JavaScript
Update Style of a Component Onscroll in React.Js
Invalid Hook Call. Hooks Can Only Be Called Inside of the Body of a Function Component
Pass Parameters in Setinterval Function
Referencing "This" Inside Setinterval/Settimeout Within Object Prototype Methods
How to Limit Google Autocomplete Results to City and Country Only
Need to Escape a Special Character in a Jquery Selector String
How to Set Locale in Datepipe in Angular 2