вызов метода родительского controllerа из директивы в AngularJS

Следуя моему предыдущему вопросу , я теперь пытаюсь вызвать метод на родительском controllerе из моей директивы. Я получаю неопределенный параметр. Вот что я делаю:

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

И сценарий:

 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 { restrict: 'E', template: "
{{mandatePerson.id}}
", replace: true, scope: { mandatePerson: '=', updateparent: '&' } } } )

когда вызывается метод updatePerson, человек не определен.

jsfiddle здесь: http://jsfiddle.net/graphicsxp/Z5MBf/7/

Просто измените свой html, как показано ниже.

   

вы не передаете «человек» с updatePerson, поэтому он не работает

Доступ к методу controllerа означает доступ к методу в родительской области из директивного controllerа / ссылки / области.

Если директива разделяет / наследует родительскую область, то довольно просто просто вызвать метод родительской области.

Требуется немного больше работы, если вы хотите получить доступ к методу родительской области видимости из изолированной области действия.

Существует несколько опций (может быть больше, чем указано ниже), чтобы вызвать метод родительской области из изолированной области действия или просмотреть переменные родительской области ( опция № 6 специально).

Обратите внимание, что я использовал link function в этих примерах, но вы также можете использовать directive controller основанный на требовании.

Опция 1. Через Object literal и из шаблона html директивы

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 { restrict: '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: http://plnkr.co/edit/rgKUsYGDo9O3tewL6xgr?p=preview

Вариант № 2. Через Object literal и из директивной ссылки / области

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 { restrict: '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" }] }); 

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

Вариант № 3. Через ссылку на функцию и из шаблона 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 { restrict: '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: http://plnkr.co/edit/Jo6FcYfVXCCg3vH42BIz?p=preview

Вариант № 4. Через ссылку на функцию и из директивной ссылки / области

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 { restrict: '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: http://plnkr.co/edit/BSqx2J1yCY86IJwAnQF1?p=preview

Вариант № 5: через ng-модель и двустороннюю привязку вы можете обновить переменные родительской области. , Таким образом, в некоторых случаях вам может не потребоваться вызывать функции родительской области.

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 { restrict: '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: http://plnkr.co/edit/hNui3xgzdTnfcdzljihY?p=preview

Вариант № 6: через $watch и $watchCollection Это двухсторонняя привязка для items во всех вышеприведенных примерах, если элементы изменены в родительской области, элементы в директиве также будут отражать изменения.

Если вы хотите смотреть другие атрибуты или объекты из родительской области, вы можете сделать это, используя $watch и $watchCollection как указано ниже

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 { restrict: 'E', scope: { name: '@', currentItem: '=', items: '=', selectedItems: '=ngModel' }, template: '', link: function(scope, element, attrs) { scope.$watchCollection('currentItem', function() { console.log(JSON.stringify(scope.currentItem)); }); scope.$watch('name', function() { console.log(JSON.stringify(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" }] }); 

Вы можете всегда ссылаться на документацию AngularJs для подробного объяснения директив.

Есть два способа, с помощью которых мы можем позвонить с помощью & и = .

Если я использую = для атрибута scope , тогда

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

будет изменено на

 ng-click='updateparent(mandatePerson)' 

И в директиве,

 updateparent="updatePerson()" 

изменится на

 updateparent="updatePerson" 

Здесь нет необходимости упоминать аргументы, они будут переданы в определение функции controllerа в качестве ссылки.

Использование & объясняется в других ответах.

Вот еще один образец (работает в 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}}
  • Многоуровневые таблицы (внутри другого при нажатии)
  • Переменные привязки от Service / Factory to Controllers
  • Недопустимое использование директивы ngTransclude в шаблоне
  • Угловые директивы - когда и как использовать компиляцию, controller, предварительную ссылку и пост-ссылку
  • угловая директива, инкапсулирующая задержку для ng-change
  • Угловая директива динамического шаблона Angular.js
  • AngularJS - Директивы против controllerов
  • Можете ли вы изменить templateUrl на лету?
  • Как применить директиву AngularJS на основе classа, установленного ng-classом?
  • Отложить угловое выполнение часов после $ digest (повышение DOM-события)
  • Экран загрузки Angularjs по запросу ajax
  • Давайте будем гением компьютера.