méthode d’appel du contrôleur parent à partir d’une directive dans AngularJS

Suite à ma question précédente, j’essaie maintenant d’appeler une méthode sur le contrôleur parent à partir de ma directive. Je reçois un paramètre indéfini. Voici ce que je fais:

 {{mandat.rum}} {{mandat.surname}}     

Et le script:

 var app = angular.module('myApp', []); app.controller('MainCtrl', function ($scope) { $scope.mandat = { name: "John", surname: "Doe", person: { id: 1408, firstname: "sam" } }; $scope.updatePerson = function(person) { alert(person.firstname); $scope.mandat.person = person; } }); app.directive('myDirective', function () { return { ressortingct: 'E', template: "
{{mandatePerson.id}}
", replace: true, scope: { mandatePerson: '=', updateparent: '&' } } } )

Lorsque la méthode updatePerson est appelée, la personne n’est pas définie.

jsfiddle ici: http://jsfiddle.net/graphicsxp/Z5MBf/7/

Changez simplement votre HTML comme ci-dessous

   

vous ne passez pas “person” avec updatePerson, c’est pourquoi cela ne fonctionne pas

Accéder à la méthode du contrôleur signifie accéder à une méthode sur la scope parent à partir de la directive controller / link / scope.

Si la directive partage / hérite de la scope parent, il est assez simple d’appeler une méthode de scope parent.

Un peu plus de travail est nécessaire lorsque vous souhaitez accéder à la méthode de la scope parent à partir de la scope de la directive isolée.

Il y a peu d’options (peut-être plus que celles énumérées ci-dessous) pour appeler une méthode de scope parent à partir de l’étendue de directives isolées ou surveiller les variables de scope parent ( option # 6 spécialement).

Notez que j’ai utilisé la link function dans ces exemples, mais vous pouvez également utiliser un directive controller en fonction des besoins.

Option 1. À travers le littéral object et du modèle HTML directive

index.html

     AngularJS Plunker       

Hello {{name}}!

Directive Content

Selected Items (in parent controller) set to: {{selectedItemsReturnedFromDirective}}

itemfilterTemplate.html

  

app.js

 var app = angular.module('plunker', []); app.directive('sdItemsFilter', function() { return { ressortingct: 'E', scope: { items: '=', selectedItems: '=', selectedItemsChanged: '&' }, templateUrl: "itemfilterTemplate.html" } }) app.controller('MainCtrl', function($scope) { $scope.name = 'TARS'; $scope.selectedItems = ["allItems"]; $scope.selectedItemsChanged = function(selectedItems1) { $scope.selectedItemsReturnedFromDirective = selectedItems1; } $scope.items = [{ "id": "allItems", "name": "All Items", "order": 0 }, { "id": "CaseItem", "name": "Case Item", "model": "PredefinedModel" }, { "id": "Application", "name": "Application", "model": "Bank" }] }); 

plnkr de travail: http://plnkr.co/edit/rgKUsYGDo9O3tewL6xgr?p=preview

Option 2. À travers le littéral object et à partir du lien directive / scope

index.html

     AngularJS Plunker       

Hello {{name}}!

Directive Content

Selected Items (in parent controller) set to: {{selectedItemsReturnedFromDirective}}

itemfilterTemplate.html

  

app.js

 var app = angular.module('plunker', []); app.directive('sdItemsFilter', function() { return { ressortingct: 'E', scope: { items: '=', selectedItems: '=', selectedItemsChanged: '&' }, templateUrl: "itemfilterTemplate.html", link: function (scope, element, attrs){ scope.selectedItemsChangedDir = function(){ scope.selectedItemsChanged({selectedItems:scope.selectedItems}); } } } }) app.controller('MainCtrl', function($scope) { $scope.name = 'TARS'; $scope.selectedItems = ["allItems"]; $scope.selectedItemsChanged = function(selectedItems1) { $scope.selectedItemsReturnedFromDirective = selectedItems1; } $scope.items = [{ "id": "allItems", "name": "All Items", "order": 0 }, { "id": "CaseItem", "name": "Case Item", "model": "PredefinedModel" }, { "id": "Application", "name": "Application", "model": "Bank" }] }); 

plnkr de travail: http://plnkr.co/edit/BRvYm2SpSpBK9uxNIcTa?p=preview

Option n ° 3. Grâce à la référence de fonction et à partir du modèle de directive html

index.html

     AngularJS Plunker       

Hello {{name}}!

Directive Content

Selected Items (in parent controller) set to: {{selectedItemsReturnFromDirective}}

itemfilterTemplate.html

  

app.js

 var app = angular.module('plunker', []); app.directive('sdItemsFilter', function() { return { ressortingct: 'E', scope: { items: '=', selectedItems:'=', selectedItemsChanged: '&' }, templateUrl: "itemfilterTemplate.html" } }) app.controller('MainCtrl', function($scope) { $scope.name = 'TARS'; $scope.selectedItems = ["allItems"]; $scope.selectedItemsChanged = function(selectedItems1) { $scope.selectedItemsReturnFromDirective = selectedItems1; } $scope.items = [{ "id": "allItems", "name": "All Items", "order": 0 }, { "id": "CaseItem", "name": "Case Item", "model": "PredefinedModel" }, { "id": "Application", "name": "Application", "model": "Bank" }] }); 

plnkr de travail: http://plnkr.co/edit/Jo6FcYfVXCCg3vH42BIz?p=preview

Option n ° 4. Grâce à la référence de fonction et à partir du lien / de la scope de la directive

index.html

     AngularJS Plunker       

Hello {{name}}!

Directive Content

Selected Items (in parent controller) set to: {{selectedItemsReturnedFromDirective}}

itemfilterTemplate.html

  

app.js

 var app = angular.module('plunker', []); app.directive('sdItemsFilter', function() { return { ressortingct: 'E', scope: { items: '=', selectedItems: '=', selectedItemsChanged: '&' }, templateUrl: "itemfilterTemplate.html", link: function (scope, element, attrs){ scope.selectedItemsChangedDir = function(){ scope.selectedItemsChanged()(scope.selectedItems); } } } }) app.controller('MainCtrl', function($scope) { $scope.name = 'TARS'; $scope.selectedItems = ["allItems"]; $scope.selectedItemsChanged = function(selectedItems1) { $scope.selectedItemsReturnedFromDirective = selectedItems1; } $scope.items = [{ "id": "allItems", "name": "All Items", "order": 0 }, { "id": "CaseItem", "name": "Case Item", "model": "PredefinedModel" }, { "id": "Application", "name": "Application", "model": "Bank" }] }); 

plnkr de travail: http://plnkr.co/edit/BSqx2J1yCY86IJwAnQF1?p=preview

Option n ° 5: Grâce à ng-model et à la liaison bidirectionnelle, vous pouvez mettre à jour les variables de scope parent. . Ainsi, vous n’avez peut-être pas besoin d’invoquer des fonctions d’étendue parent dans certains cas.

index.html

     AngularJS Plunker       

Hello {{name}}!

Directive Content

Selected Items (in parent controller) set to: {{selectedItems}}

itemfilterTemplate.html

  

app.js

 var app = angular.module('plunker', []); app.directive('sdItemsFilter', function() { return { ressortingct: 'E', scope: { items: '=', selectedItems: '=ngModel' }, templateUrl: "itemfilterTemplate.html" } }) app.controller('MainCtrl', function($scope) { $scope.name = 'TARS'; $scope.selectedItems = ["allItems"]; $scope.items = [{ "id": "allItems", "name": "All Items", "order": 0 }, { "id": "CaseItem", "name": "Case Item", "model": "PredefinedModel" }, { "id": "Application", "name": "Application", "model": "Bank" }] }); 

plnkr de travail: http://plnkr.co/edit/hNui3xgzdTnfcdzljihY?p=preview

Option n ° 6: via $watch et $watchCollection Il s’agit d’une liaison bidirectionnelle pour les items de tous les exemples ci-dessus. Si des éléments sont modifiés dans la scope parent, les éléments de directive reflètent également les modifications.

Si vous voulez regarder d’autres atsortingbuts ou objects de la scope parent, vous pouvez le faire en utilisant $watch et $watchCollection comme indiqué ci-dessous.

html

     AngularJS Plunker       

Hello {{user}}!

directive is watching name and current item

Id:
Name:
Model:

Directive Contents

Selected Items (in parent controller) set to: {{selectedItems}}

script app.js

 var app = angular.module('plunker', []); app.directive('sdItemsFilter', function() { return { ressortingct: 'E', scope: { name: '@', currentItem: '=', items: '=', selectedItems: '=ngModel' }, template: '', link: function(scope, element, attrs) { scope.$watchCollection('currentItem', function() { console.log(JSON.ssortingngify(scope.currentItem)); }); scope.$watch('name', function() { console.log(JSON.ssortingngify(scope.name)); }); } } }) app.controller('MainCtrl', function($scope) { $scope.user = 'World'; $scope.addItem = function() { $scope.items.push({ id: $scope.id, name: $scope.name, model: $scope.model }); $scope.currentItem = {}; $scope.currentItem.id = $scope.id; $scope.currentItem.name = $scope.name; $scope.currentItem.model = $scope.model; } $scope.selectedItems = ["allItems"]; $scope.items = [{ "id": "allItems", "name": "All Items", "order": 0 }, { "id": "CaseItem", "name": "Case Item", "model": "PredefinedModel" }, { "id": "Application", "name": "Application", "model": "Bank" }] }); 

Vous pouvez toujours consulter la documentation AngularJs pour des explications détaillées sur les directives.

Il existe deux manières d’appeler avec & et = .

Si j’utilise = pour un atsortingbut de scope , alors

 ng-click='updateparent({person: mandatePerson})' 

sera changé pour

 ng-click='updateparent(mandatePerson)' 

Et dans la directive,

 updateparent="updatePerson()" 

va changer à

 updateparent="updatePerson" 

Nul besoin de mentionner les arguments ici, ils seront transmis à la définition de la fonction du contrôleur comme référence.

L’utilisation de & est expliquée dans d’autres réponses.

Voici un autre modèle (fonctionne en angular 1.5 ).

 angular.module('module', []) .controller('MyController', function() { var self = this; self.msg = 0; // implement directive event listener interface this.onEvent = function(arg) { self.msg++; }; }) .directive('myDirective', function() { return { scope: { data: '=', handler: '=' }, template: '' } }); 
  
{{ctrl.msg}}