Um controlador AngularJS pode herdar de outro controlador no mesmo módulo?

Dentro de um módulo, um controlador pode herdar propriedades de um 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}); }); 

Exemplo via: link Dead : http://blog.omkarpatil.com/2013/02/controller-inheritance-in-angularjs.html

Também pode um controlador dentro de um módulo herdar de um irmão?

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

O segundo código não funciona, pois $injector.invoke requer uma function como primeiro parâmetro e não encontra a referência a ParentCtrl .

Sim, é possível, mas você precisa usar o serviço $controller para instanciar o 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 }); 

Caso você esteja usando a syntax do controlador vm , aqui está a minha solução:

 .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})); }) 

Infelizmente, você não pode usar $controller.call(vm, 'BaseGenericCtrl'...) , para passar o contexto atual para a function de encerramento (for reload() ), portanto, apenas uma solução é usar this function dentro de inheritance para alterar dinamicamente o contexto.

Eu acho que você deveria usar fábrica ou serviço para fornecer funções ou dados acessíveis para ambos os controladores.

aqui é semelhante pergunta —> AngularJS controlador de inheritance

Em resposta à questão levantada nesta resposta por gmontague , eu encontrei um método para herdar um controlador usando $ controller (), e ainda uso a syntax do controlador “as”.

Em primeiro lugar, use a syntax “as” quando você herdar a chamada $ 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); }); 

Em seguida, no modelo HTML, se a propriedade for definida pelo pai, use o parent. recuperar propriedades herdadas do pai; se definido por filho, use child. para recuperá-lo.

  
{{ parent.foo }}

Bem, eu fiz isso de outra maneira. No meu caso, eu queria uma function que aplicasse as mesmas funções e propriedades em outros controladores. Eu gostei, exceto pelos parâmetros. Desta forma, todos os seus ChildCtrls precisam receber $ 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 mencionado na resposta aceita, você pode “herdar” as modificações de um controlador pai para $ scope e outros serviços chamando: $controller('ParentCtrl', {$scope: $scope, etc: etc}); no seu controlador filho.

No entanto , isso falhará se você estiver acostumado a usar a syntax do controlador ‘as’, por exemplo, em

 
{{ child.foo }}

Se foo foi definido no controlador pai (via this.foo = ... ), o controlador filho não terá access a ele.

Como mencionado nos comentários, você pode atribuir o resultado de $ controller diretamente ao escopo:

 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: Você deve remover a parte ‘as’ do ng-controller= , porque você está especificando o nome da instância no código e não o modelo.

Para aqueles que se perguntam, você pode estender os controladores de componentes da mesma maneira, usando o método na resposta aceita.

Use a seguinte abordagem:

Componente pai (a partir de):

 /** * 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 filho (aquele que se estende):

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

O truque é usar controladores nomeados, em vez de defini-los na definição do componente.

Eu estava usando a syntax “Controller as” com vm = this e queria herdar um controlador. Eu tive problemas se meu controlador pai tivesse uma function que modificasse uma variável.

Usando as respostas de IProblemFactory e Salman Abbas , fiz o seguinte para ter access às variables ​​pai:

 (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})); }; })(); 
  
-- {{childCtrl.foo}} --

Você pode usar um mecanismo simples de inheritance JavaScript. Também não esqueça de passar um serviço angular necessário para invocar o 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); 

Consulte abaixo o link mencionado para o número de inheritances do AngularJs.

Herança-em-angular do controlador-em-angular