varios que otro llamar funcion entre directivas controladores controlador conectar comunicacion angularjs inheritance angularjs-controller

que - ¿Puede un controlador AngularJS heredar de otro controlador en el mismo módulo?



que es un modulo en angular (10)

Dentro de un módulo, un controlador puede heredar propiedades de un controlador externo:

var app = angular.module(''angularjs-starter'', []); var ParentCtrl = function ($scope, $location) { }; app.controller(''ChildCtrl'', function($scope, $injector) { $injector.invoke(ParentCtrl, this, {$scope: $scope}); });

Ejemplo a través de: Enlace muerto : http://blog.omkarpatil.com/2013/02/controller-inheritance-in-angularjs.html

¿También puede un controlador dentro de un módulo heredar de un hermano?

var app = angular.module(''angularjs-starter'', []); app.controller(''ParentCtrl '', function($scope) { //I''m the sibling, but want to act as parent }); app.controller(''ChildCtrl'', function($scope, $injector) { $injector.invoke(ParentCtrl, this, {$scope: $scope}); //This does not work });

El segundo código no funciona ya que $injector.invoke requiere una función como primer parámetro y no encuentra la referencia a ParentCtrl .


Bueno, lo hice de otra manera. En mi caso, quería una función que aplique las mismas funciones y propiedades en otros controladores. Me ha gustado, excepto por los parámetros. De esta manera, todos sus ChildCtrls necesitan recibir $ location.

var app = angular.module(''angularjs-starter'', []); function BaseCtrl ($scope, $location) { $scope.myProp = ''Foo''; $scope.myMethod = function bar(){ /* do magic */ }; } app.controller(''ChildCtrl'', function($scope, $location) { BaseCtrl.call(this, $scope, $location); // it works $scope.myMethod(); });


Como se mencionó en la respuesta aceptada, puede "heredar" las modificaciones de un controlador principal a $ scope y otros servicios llamando a: $controller(''ParentCtrl'', {$scope: $scope, etc: etc}); en el controlador de su hijo.

Sin embargo , esto falla si está acostumbrado a usar la sintaxis del controlador ''como'', por ejemplo en

<div ng-controller="ChildCtrl as child">{{ child.foo }}</div>

Si se configuró foo en el controlador principal (a través de this.foo = ... ), el controlador secundario no tendrá acceso a él.

Como se mencionó en los comentarios, puede asignar el resultado de $ controller directamente al alcance:

var app = angular.module(''angularjs-starter'', []); app.controller(''ParentCtrl '', function(etc...) { this.foo = ''bar''; }); app.controller(''ChildCtrl'', function($scope, $controller, etc...) { var inst = $controller(''ParentCtrl'', {etc: etc, ...}); // Perform extensions to inst inst.baz = inst.foo + " extended"; // Attach to the scope $scope.child = inst; });

Nota: luego debe eliminar la parte ''como'' de ng-controller= , porque está especificando el nombre de la instancia en el código y ya no la plantilla.



Creo que debería usar la fábrica o el servicio para proporcionar funciones o datos accesibles para ambos controladores.

Aquí hay una pregunta similar ---> Herencia del controlador AngularJS


En caso de que esté utilizando la sintaxis del controlador vm , aquí está mi solución:

.controller("BaseGenericCtrl", function ($scope) { var vm = this; vm.reload = reload; vm.items = []; function reload() { // this function will come from child controller scope - RESTDataService.getItemsA this.getItems(); } }) .controller("ChildCtrl", function ($scope, $controller, RESTDataService) { var vm = this; vm.getItems = RESTDataService.getItemsA; angular.extend(vm, $controller(''BaseGenericCtrl'', {$scope: $scope})); })

Desafortunadamente, no puede usar $controller.call(vm, ''BaseGenericCtrl''...) , para pasar el contexto actual a la función de cierre (para reload() ), por lo tanto, solo una solución es usar this función heredada interna para Cambiar dinámicamente el contexto.


En respuesta al problema planteado en esta respuesta por gmontague , he encontrado un método para heredar un controlador usando $ controller (), y aún uso el controlador "como" sintaxis.

En primer lugar, use la sintaxis "como" cuando herede llamar a $ controller ():

app.controller(''ParentCtrl'', function(etc...) { this.foo = ''bar''; }); app.controller(''ChildCtrl'', function($scope, $controller, etc...) { var ctrl = $controller(''ParentCtrl as parent'', {etc: etc, ...}); angular.extend(this, ctrl); });

Luego, en la plantilla HTML, si la propiedad está definida por el padre, entonces use el parent. para recuperar las propiedades heredadas de los padres; Si está definido por child, use child. para recuperarlo.

<div ng-controller="ChildCtrl as child">{{ parent.foo }}</div>


Estaba usando la sintaxis de "Controlador como" con vm = this y quería heredar un controlador. Tenía problemas si mi controlador principal tenía una función que modificaba una variable.

Usando las IProblemFactory''s y Salman Abbas , hice lo siguiente para tener acceso a las variables primarias:

(function () { ''use strict''; angular .module(''MyApp'',[]) .controller(''AbstractController'', AbstractController) .controller(''ChildController'', ChildController); function AbstractController(child) { var vm = child; vm.foo = 0; vm.addToFoo = function() { vm.foo+=1; } }; function ChildController($controller) { var vm = this; angular.extend(vm, $controller(''AbstractController'', {child: vm})); }; })();

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-controller="ChildController as childCtrl" layout="column" ng-cloak="" ng-app="MyApp"> <button type="button" ng-click="childCtrl.addToFoo()"> add </button> <span> -- {{childCtrl.foo}} -- </span> </div>


Para aquellos que se lo pregunten, puede extender los controladores de componentes de la misma manera, utilizando el método en la respuesta aceptada.

Utilice el siguiente enfoque:

Componente padre (para extender desde):

/** * 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; }; });

Componente hijo (el que se extiende):

/** * Module definition and dependencies */ angular.module(''App.Child'', []) /** * Component */ .component(''child'', { templateUrl: ''child.html'', controller: ''ChildCtrl'', }) /** * Controller */ .controller(''ChildCtrl'', function($controller) { //Get controllers const $ctrl = this; const $base = $controller(''ParentCtrl'', {}); //NOTE: no need to pass $parentDep in here, it is resolved automatically //if it''s a global service/dependency //Extend angular.extend($ctrl, $base); /** * On init */ this.$onInit = function() { //Call parent init $base.$onInit.call(this); //Do other stuff this.somethingElse = true; }; });

El truco es usar controladores con nombre, en lugar de definirlos en la definición del componente.


Puede utilizar un mecanismo de herencia de JavaScript simple. Tampoco olvide pasar un servicio angular necesario para invocar el método .call.

//simple function (js class) function baseCtrl($http, $scope, $location, $rootScope, $routeParams, $log, $timeout, $window, modalService) {//any serrvices and your 2 this.id = $routeParams.id; $scope.id = this.id; this.someFunc = function(){ $http.get("url?id="+this.id) .then(success function(response){ .... } ) } ... } angular .module(''app'') .controller(''childCtrl'', childCtrl); //angular controller function function childCtrl($http, $scope, $location, $rootScope, $routeParams, $log, $timeout, $window, modalService) { var ctrl = this; baseCtrl.call(this, $http, $scope, $location, $rootScope, $routeParams, $log, $timeout, $window, modalService); var idCopy = ctrl.id; if($scope.id == ctrl.id){//just for sample ctrl.someFunc(); } } //also you can copy prototype of the base controller childCtrl.prototype = Object.create(baseCtrl.prototype);


Sí, puede, pero tiene que usar el servicio $controller para crear una instancia del controlador:

var app = angular.module(''angularjs-starter'', []); app.controller(''ParentCtrl'', function($scope) { // I''m the sibling, but want to act as parent }); app.controller(''ChildCtrl'', function($scope, $controller) { $controller(''ParentCtrl'', {$scope: $scope}); //This works });