13 Pregunta: ¿Puede un controlador AngularJS llamar a otro?

pregunta creada en Wed, Jun 20, 2018 12:00 AM

¿Es posible que un controlador use otro?

Por ejemplo:

Este documento HTML simplemente imprime un mensaje entregado por el controlador MessageCtrl en el archivo messageCtrl.js.

 
<html xmlns:ng="http://angularjs.org/">
<head>
    <meta charset="utf-8" />
    <title>Inter Controller Communication</title>
</head>
<body>
    <div ng:controller="MessageCtrl">
        <p>{{message}}</p>
    </div>

    <!-- Angular Scripts -->
    <script src="http://code.angularjs.org/angular-0.9.19.js" ng:autobind></script>
    <script src="js/messageCtrl.js" type="text/javascript"></script>
</body>
</html>

El archivo del controlador contiene el siguiente código:

 
function MessageCtrl()
{
    this.message = function() { 
        return "The current date is: " + new Date().toString(); 
    };
}

Que simplemente imprime la fecha actual;

Si tuviera que agregar otro controlador, el DateCtrl, que devolvió la fecha en un formato específico al MessageCtrl, ¿cómo se podría hacer esto? El marco de DI parece estar relacionado con XmlHttpRequests y acceder a los servicios.

    
570
  1. Este hilo de grupo de Google, groups.google.com/d/topic/angular/m_mn-8gnNt4/discussion , discute 5 maneras en que los controladores pueden comunicarse entre sí.
    2012-08-12 01: 49: 59Z
  2. Ya hay buenas respuestas aquí, por lo que me gustaría señalar que para el caso de uso en particular mencionado, ¿tal vez un filtro AngularJS sería una mejor solución? Solo pensé que lo mencionaría :)
    2012-11-24 19: 16: 04Z
13 Respuestas                              13                         

Hay varias formas de comunicarse entre los controladores.

El mejor es probablemente compartir un servicio:

 
function FirstController(someDataService) 
{
  // use the data service, bind to template...
  // or call methods on someDataService to send a request to server
}

function SecondController(someDataService) 
{
  // has a reference to the same instance of the service
  // so if the service updates state for example, this controller knows about it
}

Otra forma es emitir un evento en el alcance:

 
function FirstController($scope) 
{
  $scope.$on('someEvent', function(event, args) {});
  // another controller or even directive
}

function SecondController($scope) 
{
  $scope.$emit('someEvent', args);
}

En ambos casos, también puede comunicarse con cualquier directiva.

    
698
2014-10-22 13: 11: 58Z
  1. Hia, el primer ejemplo requeriría que la página web esté al tanto de todos los servicios en la pila. Que se siente como un mal olor (?). Al igual que con el segundo, ¿no debería la página web proporcionar el argumento $scope?
    2012-03-12 17: 02: 26Z
  2. ¿Qué? ¿Por qué? Todos los controladores son inyectados por la DI de Angular.
    2012-03-12 19: 43: 15Z
  3. @ JoshNoe en 1 /tienes dos controladores (o más) y ambos obtienen un servicio idéntico /compartido. Luego, tienes varias formas de comunicarte, algunas de ellas las mencionaste. Decidiría basado en su caso de uso específico. Puede poner la lógica /estado compartido en el servicio y ambos controladores solo delegan en ese servicio o incluso exportan el servicio a la plantilla. Por supuesto, el servicio también puede activar eventos ...
    2013-08-22 19: 14: 36Z
  4. Llegando tarde: ustedes saben que están discutiendo con THE Vojta de Google que trabaja en AngularJS, ¿verdad? :)
    2014-03-20 20: 54: 42Z
  5. No era obvio para mí que en mi HTML el controlador emisor de eventos tiene que ser un nodo secundario del controlador de escucha para que funcione.
    2014-05-18 05: 19: 28Z

Vea este texto: http://jsfiddle.net/simpulton/XqDxG/

También vea el siguiente video: Comunicación entre controladores

Html:

 
<div ng-controller="ControllerZero">
  <input ng-model="message" >
  <button ng-click="handleClick(message);">LOG</button>
</div>

<div ng-controller="ControllerOne">
  <input ng-model="message" >
</div>

<div ng-controller="ControllerTwo">
  <input ng-model="message" >
</div>

javascript:

 
var myModule = angular.module('myModule', []);
myModule.factory('mySharedService', function($rootScope) {
  var sharedService = {};

  sharedService.message = '';

  sharedService.prepForBroadcast = function(msg) {
    this.message = msg;
    this.broadcastItem();
  };

  sharedService.broadcastItem = function() {
    $rootScope.$broadcast('handleBroadcast');
  };

  return sharedService;
});

function ControllerZero($scope, sharedService) {
  $scope.handleClick = function(msg) {
    sharedService.prepForBroadcast(msg);
  };

  $scope.$on('handleBroadcast', function() {
    $scope.message = sharedService.message;
  });        
}

function ControllerOne($scope, sharedService) {
  $scope.$on('handleBroadcast', function() {
    $scope.message = 'ONE: ' + sharedService.message;
  });        
}

function ControllerTwo($scope, sharedService) {
  $scope.$on('handleBroadcast', function() {
    $scope.message = 'TWO: ' + sharedService.message;
  });
}

ControllerZero.$inject = ['$scope', 'mySharedService'];        

ControllerOne.$inject = ['$scope', 'mySharedService'];

ControllerTwo.$inject = ['$scope', 'mySharedService'];
    
121
2013-07-20 23: 12: 49Z
  1. El violín y el video anteriores comparten un servicio. Aquí hay un violín que usa $scope. $emit: jsfiddle.net/VxafF
    2012-08-12 01: 32: 03Z
  2. @ adardesign: Me encantaría leer el mismo ejemplo sucinto y significativo para las directivas (¡gracias por esta respuesta también!)
    2014-07-22 11: 19: 21Z
  3. Gran respuesta, utilizo myModule.service ('mySharedService', function ($rootScope) {}) en lugar de myModule.factory, ¡pero funciona sin embargo!
    2015-09-28 12: 48: 37Z
  4. Excelente. Sin embargo, tengo una pregunta: ¿Por qué agregó un controlador dentro de ControllerZero? $scope. $on ('handleBroadcast', function () {$scope.message = sharedService.message;});
    2015-12-17 08: 22: 07Z
  5. ¡El video provisto es realmente increíble! Parece que esto es lo que necesito para consultar el estado de otro controlador desde otro controlador. Sin embargo, esto no funciona utilizando la función "invocar". Funciona utilizando la acción "disparador". Entonces, efectivamente, si un controlador realiza una acción y tiene un nuevo estado, entonces tendrá que transmitir el estado, y depende de otros controladores escuchar esa transmisión y responder en consecuencia. O mejor, realice la acción en el servicio compartido y luego transmita el estado. Por favor, dime si mi entendimiento es correcto.
    2016-09-16 15: 53: 57Z

Aquí hay un ejemplo de una página de dos controladores que comparten datos del servicio:

 
<!doctype html>
<html ng-app="project">
<head>
    <title>Angular: Service example</title>
    <script src="http://code.angularjs.org/angular-1.0.1.js"></script>
    <script>
var projectModule = angular.module('project',[]);

projectModule.factory('theService', function() {  
    return {
        thing : {
            x : 100
        }
    };
});

function FirstCtrl($scope, theService) {
    $scope.thing = theService.thing;
    $scope.name = "First Controller";
}

function SecondCtrl($scope, theService) {   
    $scope.someThing = theService.thing; 
    $scope.name = "Second Controller!";
}
    </script>
</head>
<body>  
    <div ng-controller="FirstCtrl">
        <h2>{{name}}</h2>
        <input ng-model="thing.x"/>         
    </div>

    <div ng-controller="SecondCtrl">
        <h2>{{name}}</h2>
        <input ng-model="someThing.x"/>             
    </div>
</body>
</html>

También aquí: https://gist.github.com/3595424

    
52
2012-09-02 06: 51: 53Z
  1. Y si theService actualiza thing.x, ese cambio se propaga automáticamente a la entrada < input > s en FirstCtrl y SecondCtrl, ¿verdad? Y también se puede cambiar thing.x directamente a través de cualquiera de los dos < input > s (¿verdad?).
    2012-11-22 06: 19: 39Z
  2. Sí. Todos los servicios Angular son aplicaciones singletons, lo que significa que solo hay una instancia del Servicio. Referencia: docs.angularjs.org/guide/dev_guide.services.creating_services
    2013-03-19 23: 20: 56Z
  3. El enlace en mi comentario anterior es 404, así que aquí está la guía de servicios, hoy, que señala que los servicios son singletons: docs.angularjs.org/guide/services
    2014-09-01 22: 52: 55Z
  4. @ exclsr ¡Sí! Lo siento, me perdí eso antes
    2014-10-31 05: 50: 04Z
  5. Por mucho, el mejor ejemplo que he visto en la web hasta ahora. Gracias
    2015-08-19 09: 34: 32Z

Si desea llamar a un controlador a otro, hay cuatro métodos disponibles

  1. $rootScope. $emit () y $rootScope. $broadcast ()
  2. Si el segundo controlador es secundario, puede usar la comunicación principal con los hijos.
  3. Servicios de uso
  4. Tipo de hackeo - con la ayuda de angular.element ()
  

1. $rootScope. $emit () y $rootScope. $broadcast ()

El controlador y su alcance pueden ser destruidos, Pero el $rootScope permanece a través de la aplicación.Es por eso que estamos tomando $rootScope porque $rootScope es el padre de todos los ámbitos.

Si está realizando una comunicación de padres a hijos e incluso un niño quiere comunicarse con sus hermanos, puede usar $broadcast

Si está realizando una comunicación de niño a padre, no hay hermanos involucrados, entonces puede usar $rootScope. $emit

HTML

 
<body ng-app="myApp">
    <div ng-controller="ParentCtrl" class="ng-scope">
      // ParentCtrl
      <div ng-controller="Sibling1" class="ng-scope">
        // Sibling first controller
      </div>
      <div ng-controller="Sibling2" class="ng-scope">
        // Sibling Second controller
        <div ng-controller="Child" class="ng-scope">
          // Child controller
        </div>
      </div>
    </div>
</body>

Código Angularjs

 
 var app =  angular.module('myApp',[]);//We will use it throughout the example 
    app.controller('Child', function($rootScope) {
      $rootScope.$emit('childEmit', 'Child calling parent');
      $rootScope.$broadcast('siblingAndParent');
    });

app.controller('Sibling1', function($rootScope) {
  $rootScope.$on('childEmit', function(event, data) {
    console.log(data + ' Inside Sibling one');
  });
  $rootScope.$on('siblingAndParent', function(event, data) {
    console.log('broadcast from child in parent');
  });
});

app.controller('Sibling2', function($rootScope) {
  $rootScope.$on('childEmit', function(event, data) {
    console.log(data + ' Inside Sibling two');
  });
  $rootScope.$on('siblingAndParent', function(event, data) {
    console.log('broadcast from child in parent');
  });
});

app.controller('ParentCtrl', function($rootScope) {
  $rootScope.$on('childEmit', function(event, data) {
    console.log(data + ' Inside parent controller');
  });
  $rootScope.$on('siblingAndParent', function(event, data) {
    console.log('broadcast from child in parent');
  });
});

En la consola de código anterior de $emit 'childEmit' no se llamará al interior de los hermanos menores y llamará solo al principal, donde $broadcast también se llamará al interior de los hermanos y al padre. Este es el lugar donde el rendimiento entra en acción. $emit es preferible, si está utilizando la comunicación de hijo a padre porque omite algunos cheques sucios.

  

2. Si el segundo controlador es secundario, puede utilizar la comunicación entre padres e hijos

Es uno de los mejores métodos. Si quiere hacer comunicación principal con los padres donde el niño quiera comunicarse con padre inmediato , entonces no necesitará ningún tipo de $difusión o $emitir, pero si desea realizar una comunicación de padre a hijo, debe usar el servicio o $broadcast

Por ejemplo HTML: -

 
<div ng-controller="ParentCtrl">
 <div ng-controller="ChildCtrl">
 </div>
</div>

Angularjs

 
 app.controller('ParentCtrl', function($scope) {
   $scope.value='Its parent';
      });
  app.controller('ChildCtrl', function($scope) {
   console.log($scope.value);
  });

Cuando esté utilizando la comunicación hijo a padre, Angularjs buscará una variable dentro del niño. Si no está presente en el interior, elegirá ver los valores dentro del controlador principal.

  

3.Utilizar servicios

AngularJS admite los conceptos de "Separación de preocupaciones" utilizando la arquitectura de servicios. Los servicios son funciones de javascript y son responsables de realizar solo tareas específicas. Esto los convierte en una entidad individual que es mantenible y comprobable . Los servicios se utilizan para inyectar el Mecanismo de Inyección de Dependencia de Angularjs .

Código Angularjs:

 
app.service('communicate',function(){
  this.communicateValue='Hello';
});

app.controller('ParentCtrl',function(communicate){//Dependency Injection
  console.log(communicate.communicateValue+" Parent World");
});

app.controller('ChildCtrl',function(communicate){//Dependency Injection
  console.log(communicate.communicateValue+" Child World");
});

Le dará salida a Hello Child World y Hello Parent World. Según los documentos de servicios de Angular Singletons: cada componente dependiente de un servicio obtiene una referencia a la instancia única generada por la fábrica de servicios .

  

4.Kind of hack - con la ayuda de angular.element ()

Este método obtiene el ámbito () del elemento por su método Id /unique class.angular.element () devuelve el elemento y scope () proporciona la variable $scope de otra variable utilizando la variable $scope de un controlador dentro de otro no es una buena práctica.

HTML: -

 
<div id='parent' ng-controller='ParentCtrl'>{{varParent}}
 <span ng-click='getValueFromChild()'>Click to get ValueFormChild</span>
 <div id='child' ng-controller='childCtrl'>{{varChild}}
   <span ng-click='getValueFromParent()'>Click to get ValueFormParent </span>
 </div>
</div>

Angularjs: -

 
app.controller('ParentCtrl',function($scope){
 $scope.varParent="Hello Parent";
  $scope.getValueFromChild=function(){
  var childScope=angular.element('#child').scope();
  console.log(childScope.varChild);
  }
});

app.controller('ChildCtrl',function($scope){
 $scope.varChild="Hello Child";
  $scope.getValueFromParent=function(){
  var parentScope=angular.element('#parent').scope();
  console.log(parentScope.varParent);
  }
}); 

En el código anterior, los controladores muestran su propio valor en HTML y, cuando haga clic en el texto, obtendrá los valores en la consola de forma correspondiente. Si hace clic en el intervalo de los controladores principales, el navegador mostrará el valor de child y viceversa.

    
51
2017-01-25 13: 36: 43Z

Si desea emitir & transmita eventos para compartir datos o llamar a funciones entre controladores , consulte este link : y compruebe la respuesta con zbynour (responda con votos máximos). Estoy citando su respuesta!

Si el ámbito de firstCtrl es el padre del ámbito de secondCtrl, su código debería funcionar reemplazando $emit por $broadcast en firstCtrl:

 
function firstCtrl($scope){
    $scope.$broadcast('someEvent', [1,2,3]);
}

function secondCtrl($scope){
    $scope.$on('someEvent', function(event, mass) {console.log(mass)});
}

En caso de que no haya una relación padre-hijo entre sus ámbitos, puede inyectar $rootScope en el controlador y transmitir el evento a todos los ámbitos secundarios (es decir, también secondCtrl).

 
function firstCtrl($rootScope){
    $rootScope.$broadcast('someEvent', [1,2,3]);
}

Finalmente, cuando necesita enviar el evento desde el controlador secundario a los ámbitos hacia arriba, puede usar $scope. $emit. Si el ámbito de firstCtrl es principal del ámbito de secondCtrl:

 
function firstCtrl($scope){
    $scope.$on('someEvent', function(event, data) { console.log(data); });
}

function secondCtrl($scope){
    $scope.$emit('someEvent', [1,2,3]);
}
    
32
2017-05-23 12: 02: 45Z

Dos fiddles más: (enfoque sin servicio)

1) Para el controlador principal-secundario: utilizando $scope del controlador principal para emitir /transmitir eventos.       http://jsfiddle.net/laan_sachin/jnj6y/

2) Uso de $rootScope en controladores no relacionados.       http://jsfiddle.net/VxafF/

    
24
2012-10-07 17: 10: 49Z
  1. ¿Cuál es la razón de toda esta complejidad con los eventos? ¿Por qué no hacer algo como esto? jsfiddle.net/jnj6y/32
    2013-06-06 18: 50: 13Z
  2. Depende de qué tipo de relación padre-hijo sea la correcta. Puede ser una jerarquía de DOM, si los eventos de caso le permiten desacoplar cosas.
    2013-06-21 06: 14: 21Z

En realidad, el uso de emitir y transmitir es ineficiente porque el evento aumenta y disminuye la jerarquía del alcance, lo que puede degradarse fácilmente en el rendimiento de una aplicación compleja.

Sugeriría usar un servicio. Aquí es cómo lo implementé recientemente en uno de mis proyectos: https://gist.github.com/3384419.

Idea básica: registre un pub-sub /evento bus como servicio. Luego, inyecte ese bus de eventos donde sea necesario para suscribirse o publicar eventos /temas.

    
16
2017-07-04 16: 53: 19Z
  1. suena prometedor, pero el enlace no funciona
    2015-12-03 21: 58: 53Z

También sé de esta manera.

 
angular.element($('#__userProfile')).scope().close();

Pero no lo uso demasiado, porque no me gusta usar los selectores jQuery en el código angular.

    
3
2013-10-04 21: 25: 54Z
  1. la mejor respuesta. Tan simple y fácil ... =)
    2014-08-05 12: 28: 36Z
  2. @ zVictor, este es realmente un enfoque de "último recurso". Funciona, pero se está saliendo del ámbito para forzar el regreso. Esto es usar la manipulación DOM para forzar que se haga algo en lugar de hacerlo mediante programación. Es simple, funciona, pero no es escalable.
    2014-08-11 21: 14: 54Z
  3. @ BrianNoah, es cierto. Está bien usar este código para prototipos o algunos experimentos, pero no para el código de producción.
    2014-08-12 08: 03: 13Z
  4. Eso es lo peor que se puede hacer. Manipulación de DOM en servicios y acceso de alcance directo.
    2015-03-11 08: 42: 35Z

No sé si esto está fuera de los estándares pero si tiene todos sus controladores en el mismo archivo, entonces puede hacer algo como esto:

 
app = angular.module('dashboardBuzzAdmin', ['ngResource', 'ui.bootstrap']);

var indicatorsCtrl;
var perdiosCtrl;
var finesCtrl;

app.controller('IndicatorsCtrl', ['$scope', '$http', function ($scope, $http) {
  indicatorsCtrl = this;
  this.updateCharts = function () {
    finesCtrl.updateChart();
    periodsCtrl.updateChart();
  };
}]);

app.controller('periodsCtrl', ['$scope', '$http', function ($scope, $http) {
  periodsCtrl = this;
  this.updateChart = function() {...}
}]);

app.controller('FinesCtrl', ['$scope', '$http', function ($scope, $http) {
  finesCtrl = this;
  this.updateChart = function() {...}
}]);

Como puede ver, los indicadores de control están llamando a las funciones updateChart de los otros dos controladores al llamar a updateCharts.

    
3
2014-10-20 14: 41: 13Z

Hay un método que no depende de los servicios, $broadcast o $emit. No es adecuado en todos los casos, pero si tiene 2 controladores relacionados que pueden resumirse en directivas, entonces puede usar la opción require en la definición de directiva. Esto es muy probablemente como se comunican ngModel y ngForm. Puede usar esto para comunicarse entre los controladores de directivas que están anidados o en el mismo elemento.

Para un padre /hijoSituación, el uso sería el siguiente:

 
<div parent-directive>
  <div inner-directive></div>
</div>

Y los puntos principales para que funcione: en la directiva principal, con los métodos a llamar, debe definirlos en this (no en $scope):

 
controller: function($scope) {
  this.publicMethodOnParentDirective = function() {
    // Do something
  }
}

En la definición de la directiva secundaria, puede usar la opción require para que el controlador principal pase a la función de enlace (para que pueda llamar a las funciones desde la directiva secundaria scope.

 
require: '^parentDirective',
template: '<span ng-click="onClick()">Click on this to call parent directive</span>',
link: function link(scope, iElement, iAttrs, parentController) {
  scope.onClick = function() {
    parentController.publicMethodOnParentDirective();
  }
}

Lo anterior se puede ver en http://plnkr.co/edit/poeq460VmQER8Gl9w8Oz?p= vista previa

Una directiva de hermanos se usa de manera similar, pero ambas directivas en el mismo elemento:

 
<div directive1 directive2>
</div>

Se utiliza creando un método en directive1:

 
controller: function($scope) {
  this.publicMethod = function() {
    // Do something
  }
}

Y en la directiva 2, esto puede llamarse utilizando la opción require, lo que hace que se pase el controlador sibling a la función de enlace:

 
require: 'directive1',
template: '<span ng-click="onClick()">Click on this to call sibling directive1</span>',
link: function link(scope, iElement, iAttrs, siblingController) {
  scope.onClick = function() {
    siblingController.publicMethod();
  }
}

Esto se puede ver en http://plnkr.co/edit/MUD2snf9zvadfnDXq85w?png .

¿Los usos de esto?

  • Padre: Cualquier caso en el que los elementos hijos deban "registrarse" con un padre. Al igual que la relación entre ngModel y ngForm. Estos pueden agregar ciertos comportamientos que pueden afectar a los modelos. También puede tener algo basado puramente en DOM, donde un elemento padre necesita administrar las posiciones de ciertos hijos, por ejemplo, administrar o reaccionar al desplazamiento.

  • Hermanos: permite que una directiva modifique su comportamiento. ngModel es el caso clásico, para agregar analizadores /validación al uso de ngModel en las entradas.

2
2013-12-27 13: 16: 15Z

Puede inyectar el servicio '$controller' en su controlador principal (MessageCtrl) y luego crear una instancia /inyectar el controlador secundario (DateCtrl) usando:
$scope.childController = $controller('childController', { $scope: $scope.$new() });

Ahora puede acceder a los datos de su controlador secundario llamando a sus métodos, ya que es un servicio.
Déjame saber si hay algún problema.

    
2
2015-04-16 18: 56: 12Z

El siguiente es un enfoque publish-subscribe que es independiente de Angular JS.

Buscar controlador de parámetros

 
//Note: Multiple entities publish the same event
regionButtonClicked: function () 
{
        EM.fireEvent('onSearchParamSelectedEvent', 'region');
},

plantButtonClicked: function () 
{
        EM.fireEvent('onSearchParamSelectedEvent', 'plant');
},

Controlador de opciones de búsqueda

 
//Note: It subscribes for the 'onSearchParamSelectedEvent' published by the Search Param Controller
localSubscribe: function () {
        EM.on('onSearchParamSelectedEvent', this.loadChoicesView, this);

});


loadChoicesView: function (e) {

        //Get the entity name from eData attribute which was set in the event manager
        var entity = $(e.target).attr('eData');

        console.log(entity);

        currentSelectedEntity = entity;
        if (entity == 'region') {
            $('.getvalue').hide();
            this.loadRegionsView();
            this.collapseEntities();
        }
        else if (entity == 'plant') {
            $('.getvalue').hide();
            this.loadPlantsView();
            this.collapseEntities();
        }


});

Administrador de eventos

 
myBase.EventManager = {

    eventArray:new Array(),


    on: function(event, handler, exchangeId) {
        var idArray;
        if (this.eventArray[event] == null) {
            idArray = new Array();
        } else { 
            idArray = this.eventArray[event];
        }
        idArray.push(exchangeId);
        this.eventArray[event] = idArray;

        //Binding using jQuery
        $(exchangeId).bind(event, handler);
    },

    un: function(event, handler, exchangeId) {

        if (this.eventArray[event] != null) {
            var idArray = this.eventArray[event];
            idArray.pop(exchangeId);
            this.eventArray[event] = idArray;

            $(exchangeId).unbind(event, handler);
        }
    },

    fireEvent: function(event, info) {
        var ids = this.eventArray[event];

        for (idindex = 0; idindex < ids.length; idindex++) {
            if (ids[idindex]) {

                //Add attribute eData
                $(ids[idindex]).attr('eData', info);
                $(ids[idindex]).trigger(event);
            }
        }
    }
};

Global

 
var EM = myBase.EventManager;
    
1
2014-02-21 14: 10: 28Z

En angular 1.5, esto se puede lograr haciendo lo siguiente:

 
(function() {
  'use strict';

  angular
    .module('app')
    .component('parentComponent',{
      bindings: {},
      templateUrl: '/templates/products/product.html',
      controller: 'ProductCtrl as vm'
    });

  angular
    .module('app')
    .controller('ProductCtrl', ProductCtrl);

  function ProductCtrl() {
    var vm = this;
    vm.openAccordion = false;

    // Capture stuff from each of the product forms
    vm.productForms = [{}];

    vm.addNewForm = function() {
      vm.productForms.push({});
    }
  }

}());

Este es el componente padre. En esto, he creado una función que inserta otro objeto en mi arreglo productForms. Nota: este es solo mi ejemplo, esta función puede ser cualquier cosa realmente.

Ahora podemos crear otro componente que utilizará require:

 
(function() {
  'use strict';

  angular
    .module('app')
    .component('childComponent', {
      bindings: {},
      require: {
        parent: '^parentComponent'
      },
      templateUrl: '/templates/products/product-form.html',
      controller: 'ProductFormCtrl as vm'
    });

  angular
    .module('app')
    .controller('ProductFormCtrl', ProductFormCtrl);

  function ProductFormCtrl() {
    var vm = this;

    // Initialization - make use of the parent controllers function
    vm.$onInit = function() {
      vm.addNewForm = vm.parent.addNewForm;
    };  
  }

}());

Aquí, el componente secundario está creando una referencia a la función del componente principal addNewForm que luego puede vincularse al HTML y llamarse como cualquier otra función.

    
1
2016-03-23 ​​17: 10: 13Z
fuente colocada aquí