J'ai trois contrôleurs qui sont assez similaires. Je veux avoir un contrôleur que ces trois étendent et partagent ses fonctions.
De loin la solution la plus rapide, la plus propre et la plus facile pour cela! Merci!
J'ai trois contrôleurs qui sont assez similaires. Je veux avoir un contrôleur que ces trois étendent et partagent ses fonctions.
Peut-être que vous n'étendez pas un contrôleur mais il est possible d'étendre un contrôleur ou de faire d'un contrôleur unique un mixin de plusieurs contrôleurs.
module.controller('CtrlImplAdvanced', ['$scope', '$controller', function ($scope, $controller) {
// Initialiser la super classe et l'étendre.
angular.extend(this, $controller('CtrlImpl', {$scope: $scope}));
… Extensions supplémentaires pour créer un mixin.
}]);
Lorsque le contrôleur parent est créé, la logique qu'il contient est également exécutée. Voir $controller() pour plus d'informations à ce sujet, mais seule la valeur $scope
doit être passée. Toutes les autres valeurs seront injectées normalement.
@mwarren, votre préoccupation est prise en charge automatiquement par l'injection de dépendance Angular. Tout ce que vous avez à faire est d'injecter $scope, bien que vous puissiez remplacer les autres valeurs injectées si vous le souhaitez. Voici un exemple:
(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);
Origine depuis le Contrôleur: {{C.getOrigin()}}
Bien que $document ne soit pas passé dans 'simpleController' lorsqu'il est créé par 'complexController', $document est injecté pour nous.
Je pense que vous n'avez pas besoin de $.extend()
, vous pouvez simplement appeler $controller('CtrlImpl', {$scope: $scope});
Pour l'héritage, vous pouvez utiliser des modèles d'héritage JavaScript standard. Voici une démo qui utilise $injector
function Parent($scope) {
$scope.name = 'Humain';
$scope.clickParent = function() {
$scope.name = 'Cliqué depuis le contrôleur de base';
}
}
function Child($scope, $injector) {
$injector.invoke(Parent, this, {$scope: $scope});
$scope.name = 'Enfant humain';
$scope.clickChild = function(){
$scope.clickParent();
}
}
Child.prototype = Object.create(Parent.prototype);
Si vous utilisez la syntaxe controllerAs
(que je recommande vivement), il est encore plus facile d'utiliser le modèle d'héritage classique :
function BaseCtrl() {
this.name = 'foobar';
}
BaseCtrl.prototype.parentMethod = function () {
//corps
};
function ChildCtrl() {
BaseCtrl.call(this);
this.name = 'baz';
}
ChildCtrl.prototype = Object.create(BaseCtrl.prototype);
ChildCtrl.prototype.childMethod = function () {
this.parentMethod();
//corps
};
app.controller('BaseCtrl', BaseCtrl);
app.controller('ChildCtrl', ChildCtrl);
Une autre façon pourrait être de créer simplement une fonction constructeur "abstraite" qui sera votre contrôleur de base :
function BaseController() {
this.click = function () {
//actions ici
};
}
module.controller('ChildCtrl', ['$scope', function ($scope) {
BaseController.call($scope);
$scope.anotherClick = function () {
//autres actions
};
}]);
Eh bien, je ne suis pas tout à fait sûr de ce que vous voulez réaliser, mais en général, les Services sont la meilleure solution. Vous pouvez également utiliser les caractéristiques de l'héritage de portée d'Angular pour partager du code entre les contrôleurs:
function ParentCtrl($scope) {
$scope.fx = function() {
alert("Bonjour le monde");
});
}
function FirstChildCtrl($scope) {
// $scope.fx() est disponible ici
}
function SecondChildCtrl($scope) {
// $scope.fx() est disponible ici
}
Partager les mêmes variables et fonctions entre les contrôleurs qui font des choses similaires (l'un est pour l'édition, un autre pour la création, etc.). C'est certainement l'une des solutions...
$scope héritage est de loin la meilleure façon de le faire, bien mieux que la réponse acceptée.
Au final, cela semblait être la façon la plus angulaire d'aller. J'ai trois parentControllers très brefs sur trois pages différentes qui définissent simplement une valeur $scope que le childController peut récupérer. Le childController, que j'avais initialement envisagé d'étendre, contient toute la logique du contrôleur.
Merci, mais j'ai 4 fonctions qui utilisent déjà des services (enregistrer, supprimer, etc.) et qui existent dans les trois contrôleurs. Si l'extension n'est pas une option, y a-t-il une possibilité pour un 'mixin' ?
Ne mélangez pas. Vous pourriez créer un autre service qui gère ces méthodes de service (enregistrer, supprimer, ...). Plus vous pourrez déplacer la logique d'application hors de votre contrôleur, mieux ce sera.
Vous pouvez créer un service et hériter de son comportement dans n'importe quel contrôleur simplement en l'injectant.
app.service("reusableCode", function() {
var reusableCode = {};
reusableCode.commonMethod = function() {
alert('Bonjour, le Monde !');
};
return reusableCode;
});
Ensuite, dans votre contrôleur où vous souhaitez étendre le service reusableCode ci-dessus :
app.controller('MainCtrl', function($scope, reusableCode) {
angular.extend($scope, reusableCode);
// maintenant vous pouvez accéder à toutes les propriétés de reusableCode dans ce $scope
$scope.commonMethod()
});
DEMO PLUNKER: http://plnkr.co/edit/EQtj6I0X08xprE8D0n5b?p=preview
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.