вызов метода родительского 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, человек не определен.
- Когда в пользу ng-if vs. ng-show / ng-hide?
- Доступ к атрибутам из директивы AngularJS
- Угловое название директивы: допускаются только строчные буквы?
- Как установить фокус на поле ввода?
- Как выбрать элемент по имени classа с помощью jqLite?
jsfiddle здесь: http://jsfiddle.net/graphicsxp/Z5MBf/7/
- Как разрешить ввод только числа (цифры и десятичная точка) на входе?
- Угловой ng-стиль с условным выражением
- Понимание опции transclude определения директивы?
- Пользовательская форма проверки валидации для сравнения двух полей
- получить исходный элемент из ng-click
- Несколько директив , запрашивающих новую / выделенную область
- AngularJS - Динамическое создание элементов, определяющих директивы
- Предварительный просмотр изображения перед загрузкой Angularjs
Просто измените свой 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}}