Un contrôleur AngularJS peut-il en appeler un autre?

581

Est-il possible qu'un contrôleur utilise un autre?

Par exemple:

Ce document HTML imprime simplement un message délivré par le MessageCtrlcontrôleur dans le messageCtrl.jsfichier.

<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>

Le fichier du contrôleur contient le code suivant:

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

Qui imprime simplement la date actuelle;

Si je devais ajouter un autre contrôleur, DateCtrlqui a remis la date dans un format spécifique MessageCtrl, comment procéderait-on? Le cadre DI semble s'intéresser XmlHttpRequestsaux services et y accéder.

BanksySan
la source
4
Ce fil de discussion sur les groupes Google, groups.google.com/d/topic/angular/m_mn-8gnNt4/discussion , décrit 5 façons dont les contrôleurs peuvent communiquer entre eux.
Mark Rajcok
Il y a déjà de bonnes réponses ici, donc je voudrais juste souligner que pour le cas d'utilisation particulier mentionné, peut-être qu'un filtre AngularJS serait une meilleure solution? Je pensais juste le mentionner :)
Joe Dyndale

Réponses:

705

Il existe plusieurs façons de communiquer entre les contrôleurs.

Le meilleur est probablement de partager un service:

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
}

Une autre façon est d'émettre un événement sur la portée:

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

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

Dans les deux cas, vous pouvez également communiquer avec n'importe quelle directive.

Vojta
la source
4
Hia, Le premier exemple nécessiterait que la page Web connaisse tous les services de la pile. Ce qui ressemble à une mauvaise odeur (?). Comme pour le second, la page Web n'aurait-elle pas besoin de fournir l'argument $ scope?
BanksySan
54
Quelle? Pourquoi? Tous les contrôleurs sont injectés par DI angulaire.
Vojta
7
@JoshNoe dans 1 / vous avez deux contrôleurs (ou plus) et ils ont tous deux un service identique / partagé. Ensuite, vous avez plusieurs façons de communiquer, dont certaines que vous avez mentionnées. Je déciderais en fonction de votre cas d'utilisation spécifique. Vous pouvez mettre la logique / l'état partagé dans le service et les deux contrôleurs délèguent uniquement à ce service ou même exportent le service vers le modèle. Bien sûr, le service peut également déclencher des événements ...
Vojta
137
J'arrive tard: vous savez que vous vous disputez avec THE Vojta de Google qui travaille sur AngularJS, non? :)
Suman
16
Il n'était pas évident pour moi que dans mon HTML, le contrôleur émetteur d'événements doit être un nœud enfant du contrôleur d'écoute pour qu'il fonctionne.
djangonaut
122

Voir ce violon: http://jsfiddle.net/simpulton/XqDxG/

Regardez également la vidéo suivante: Communiquer entre les contrôleurs

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'];
adardesign
la source
12
Le violon et la vidéo ci-dessus partagent un service. Voici un violon qui utilise $ scope. $ Emit
Mark Rajcok
1
@adardesign: J'AIMERAIS lire le même exemple succinct et significatif pour les directives (merci aussi pour cette réponse!)
sscarduzio
Excellente réponse, j'utilise myModule.service ('mySharedService', function ($ rootScope) {}) au lieu de myModule.factory mais cela fonctionne quand même!
TacoEater
Excellent. Cependant, j'ai une question: pourquoi avez-vous ajouté un gestionnaire dans ControllerZero? $ scope. $ on ('handleBroadcast', function () {$ scope.message = sharedService.message;});
ZooZ
La vidéo fournie est vraiment géniale! Il me semble que c'est ce dont j'ai besoin pour demander l'état d'un autre contrôleur à un autre contrôleur. Cependant, cela ne fonctionne pas en utilisant la fonction "invoke". Il fonctionne en utilisant l'action "déclencheur". Si efficacement, si un contrôleur exécute une action et a un nouvel état, alors il devra diffuser l'état, et c'est aux autres contrôleurs d'écouter cette diffusion et de répondre en conséquence. Ou mieux, effectuez l'action dans le service partagé, puis diffusez l'état. Veuillez me dire si ma compréhension est correcte.
tarekahf
53

Si vous souhaitez appeler un contrôleur dans un autre, quatre méthodes sont disponibles

  1. $ rootScope. $ emit () et $ rootScope. $ broadcast ()
  2. Si le deuxième contrôleur est enfant, vous pouvez utiliser la communication parent-enfant.
  3. Utiliser les services
  4. Type de piratage - avec l'aide de angular.element ()

1. $ rootScope. $ Emit () et $ rootScope. $ Broadcast ()

Le contrôleur et sa portée peuvent être détruits, mais $ rootScope reste dans l'application, c'est pourquoi nous prenons $ rootScope parce que $ rootScope est le parent de toutes les portées.

Si vous effectuez une communication du parent à l'enfant et que même l'enfant souhaite communiquer avec ses frères et sœurs, vous pouvez utiliser $ broadcast

Si vous effectuez une communication de l'enfant au parent, aucun frère ou sœur n'est impliqué, vous pouvez utiliser $ 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>

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

Dans la console de code ci-dessus, $ emit 'childEmit' n'appellera pas à l'intérieur des frères et sœurs enfants et il appellera uniquement à l'intérieur du parent, où $ broadcast sera également appelé à l'intérieur des frères et sœurs.C'est l'endroit où les performances entrent en action. préférable, si vous utilisez la communication de l'enfant à ses parents, car elle saute quelques vérifications sales.

2. Si le deuxième contrôleur est enfant, vous pouvez utiliser la communication enfant-parent

C'est l'une des meilleures méthodes, si vous voulez faire une communication parent-enfant là où l'enfant veut communiquer avec le parent immédiat, alors il n'aurait besoin d'aucune sorte $ broadcast ou $ emit mais si vous voulez faire la communication du parent à l'enfant, vous devez utiliser le service ou $ broadcast

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

Chaque fois que vous utilisez la communication enfant-parent, Angularjs recherchera une variable à l'intérieur de l'enfant. Si elle n'est pas présente à l'intérieur, elle choisira de voir les valeurs à l'intérieur du contrôleur parent.

3.Utilisez les services

AngularJS prend en charge les concepts de "séparation des préoccupations" en utilisant l'architecture des services. Les services sont des fonctions javascript et sont chargés de faire des tâches spécifiques uniquement, ce qui en fait une entité individuelle qui est maintenable et testable .Services utilisés pour injecter en utilisant le mécanisme d'injection de dépendance d'Angularjs.

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

Il donnera la sortie Hello Child World et Hello Parent World. Selon Angular docs of services Singletons - Chaque composant dépendant d'un service obtient une référence à l'instance unique générée par la fabrique de services .

4.Hack of hack - avec l'aide de angular.element ()

Cette méthode obtient scope () de l'élément par sa méthode Id / unique class.angular.element () renvoie element et scope () donne la variable $ scope d'une autre variable en utilisant la variable $ scope d'un contrôleur à l'intérieur d'un autre n'est pas une bonne pratique.

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

Dans le code ci-dessus, les contrôleurs affichent leur propre valeur en HTML et lorsque vous cliquerez sur du texte, vous obtiendrez des valeurs dans la console en conséquence. Si vous cliquez sur la portée des contrôleurs parents, le navigateur consolera la valeur de l'enfant et vice versa.

Shubham Nigam
la source
52

Voici un exemple d'une page de deux contrôleurs partageant des données de service:

<!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>

Également ici: https://gist.github.com/3595424

exclsr
la source
Et si les theServicemises à jour thing.x, alors ce changement se propage automatiquement aux <input> dans FirstCtrlet SecondCtrl, non? Et on peut également changer thing.xdirectement via l'un des deux <input> (non?).
KajMagnus
4
Oui. Tous les services angulaires sont des singletons d'application, ce qui signifie qu'il n'y a qu'une seule instance de theService. Référence: docs.angularjs.org/guide/dev_guide.services.creating_services
exclsr
Le lien dans mon commentaire précédent est 404, alors voici le guide des services, aujourd'hui, qui note que les services sont des singletons: docs.angularjs.org/guide/services
exclsr
1
@exclsr Oui! Désolé d'avoir manqué ça avant
CodyBugstein
3
De loin le meilleur exemple que j'ai vu sur le web jusqu'à présent. Merci
Sevenearths
33

Si vous cherchez à émettre et à diffuser des événements pour partager des données ou des fonctions d'appel entre contrôleurs , veuillez consulter ce lien : et vérifiez la réponse par zbynour(réponse avec un maximum de votes). Je cite sa réponse !!!

Si la portée de firstCtrl est parent de la portée secondCtrl, votre code devrait fonctionner en remplaçant $ emit par $ broadcast dans firstCtrl:

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

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

Dans le cas où il n'y a pas de relation parent-enfant entre vos étendues, vous pouvez injecter $ rootScope dans le contrôleur et diffuser l'événement à toutes les étendues enfants (c'est-à-dire aussi secondCtrl).

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

Enfin, lorsque vous devez répartir l'événement du contrôleur enfant vers des étendues vers le haut, vous pouvez utiliser $ scope. $ Emit. Si l'étendue de firstCtrl est parent de l'étendue de secondCtrl:

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

function secondCtrl($scope){
    $scope.$emit('someEvent', [1,2,3]);
}
SharpCoder
la source
24

Deux autres violons: (approche hors service)

1) Pour le contrôleur parent-enfant - Utilisation $scopedu contrôleur parent pour émettre / diffuser des événements. http://jsfiddle.net/laan_sachin/jnj6y/

2) Utilisation $rootScopesur plusieurs contrôleurs non liés. http://jsfiddle.net/VxafF/

Chevalier noir
la source
Quelle raison de toute cette complexité des événements? Pourquoi ne pas faire quelque chose comme ça? jsfiddle.net/jnj6y/32
Dfr
Cela dépend du type de relation parent-enfant qui convient. Il peut s'agir d'une hiérarchie DOM, c'est-à-dire que les événements de cas vous permettent de découpler les choses.
DarkKnight
17

En fait, utiliser émettre et diffuser est inefficace car l'événement bouillonne de haut en bas dans la hiérarchie de la portée, ce qui peut facilement se dégrader en réduction des performances pour une application complexe.

Je suggère d'utiliser un service. Voici comment je l'ai récemment implémenté dans l'un de mes projets - https://gist.github.com/3384419 .

Idée de base - enregistrer un bus pub-sub / événement en tant que service. Ensuite, injectez ce bus d'événements partout où vous devez vous abonner ou publier des événements / sujets.

numan salati
la source
5

Je connais aussi cette façon.

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

Mais je ne l'utilise pas trop, car je n'aime pas utiliser les sélecteurs jQuery en code angulaire.

Andrey Korchak
la source
la meilleure réponse. Si simple et facile ... =)
zVictor
3
@zVictor, c'est vraiment une approche de "dernier recours". Cela fonctionne, mais cela sort du cadre afin de forcer votre retour. Cela utilise la manipulation DOM pour forcer quelque chose à faire au lieu de le faire par programme. C'est simple, cela fonctionne, mais ce n'est pas évolutif.
Brian Noah
2
@BrianNoah, c'est vrai. Vous pouvez utiliser ce code pour les prototypes ou certaines expériences, mais pas pour le code de production.
Andrey Korchak
1
C'est le pire qui puisse être fait. Manipulation DOM dans les services et accès direct à la portée.
Mattia Franchetto
3

Il existe une méthode qui ne dépend pas des services, $broadcastou $emit. Ce n'est pas approprié dans tous les cas, mais si vous avez 2 contrôleurs associés qui peuvent être résumés en directives, alors vous pouvez utiliser l' requireoption dans la définition de directive. C'est probablement la façon dont ngModel et ngForm communiquent. Vous pouvez l'utiliser pour communiquer entre des contrôleurs de directives imbriqués ou sur le même élément.

Pour une situation parent / enfant, l'utilisation serait la suivante:

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

Et les points principaux pour le faire fonctionner: Sur la directive parent, avec les méthodes à appeler, vous devez les définir sur this(pas sur $scope):

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

Dans la définition de la directive enfant, vous pouvez utiliser l' requireoption pour que le contrôleur parent soit passé à la fonction de liaison (afin que vous puissiez ensuite y appeler des fonctions à partir scopede la directive enfant.

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

Ce qui précède peut être vu à http://plnkr.co/edit/poeq460VmQER8Gl9w8Oz?p=preview

Une directive frère est utilisée de la même manière, mais les deux directives sur le même élément:

<div directive1 directive2>
</div>

Utilisé en créant une méthode sur directive1:

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

Et dans directive2, cela peut être appelé en utilisant l' requireoption qui entraîne le passage de siblingController à la fonction de liaison:

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

Cela peut être vu à http://plnkr.co/edit/MUD2snf9zvadfnDXq85w?p=preview .

Les utilisations de cela?

  • Parent: Tout cas où les éléments enfants doivent «s'enregistrer» eux-mêmes auprès d'un parent. Tout comme la relation entre ngModel et ngForm. Ceux-ci peuvent ajouter certains comportements qui peuvent affecter les modèles. Vous pouvez également avoir quelque chose de purement basé sur DOM, où un élément parent doit gérer les positions de certains enfants, par exemple pour gérer ou réagir au défilement.

  • Fratrie: permettre à une directive de voir son comportement modifié. ngModel est le cas classique, pour ajouter des analyseurs / validation à l'utilisation de ngModel sur les entrées.

Michal Charemza
la source
3

Je ne sais pas si cela est hors normes mais si vous avez tous vos contrôleurs sur le même fichier, vous pouvez faire quelque chose comme ceci:

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

Comme vous pouvez le voir, indicateursCtrl appelle les fonctions updateChart des deux autres contrôleurs lors de l'appel à updateCharts.

tomascharad
la source
2

Vous pouvez injecter le service '$ controller' dans votre contrôleur parent (MessageCtrl) puis instancier / injecter le contrôleur enfant (DateCtrl) en utilisant:
$scope.childController = $controller('childController', { $scope: $scope.$new() });

Vous pouvez maintenant accéder aux données de votre contrôleur enfant en appelant ses méthodes car il s'agit d'un service.
Faites-moi savoir s'il y a un problème.

Smrutiranjan Sahu
la source
1

Voici une publish-subscribeapproche qui est indépendante de JS angulaire.

Contrôleur de paramètres de recherche

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

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

Contrôleur de choix de recherche

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


});

Responsable de l'événement

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;
LCJ
la source
1

Dans la version 1.5 angulaire, cela peut être accompli en procédant comme suit:

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

}());

Il s'agit du composant parent. En cela, j'ai créé une fonction qui pousse un autre objet dans mon productFormstableau - note - ceci est juste mon exemple, cette fonction peut être n'importe quoi vraiment.

Nous pouvons maintenant créer un autre composant qui utilisera 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;
    };  
  }

}());

Ici, le composant enfant crée une référence à la fonction du composant parents addNewFormqui peut ensuite être liée au HTML et appelée comme toute autre fonction.

Katana24
la source