Acceder al método del controlador significa acceder a un método en el alcance principal desde el controlador / enlace / alcance de la directiva.
Si la directiva comparte / hereda el ámbito primario, entonces es bastante sencillo invocar un método de ámbito primario.
Se requiere un poco más de trabajo cuando desea acceder al método de ámbito primario desde el ámbito de directiva aislado.
Hay pocas opciones (pueden ser más que las que se enumeran a continuación) para invocar un método de alcance primario desde el alcance de directivas aisladas o ver variables de alcance primario ( opción # 6 especialmente).
Tenga en cuenta que lo utilicé link function
en estos ejemplos, pero también puede utilizarlo directive controller
según los requisitos.
Opción 1. A través del objeto literal y de la plantilla html de la directiva
index.html
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<p> Directive Content</p>
<sd-items-filter selected-items="selectedItems" selected-items-changed="selectedItemsChanged(selectedItems)" items="items"> </sd-items-filter>
<P style="color:red">Selected Items (in parent controller) set to: {{selectedItemsReturnedFromDirective}} </p>
</body>
</html>
itemfilterTemplate.html
<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" ng-change="selectedItemsChanged({selectedItems:selectedItems})" ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'">
<option>--</option>
</select>
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"
}]
});
trabajo plnkr: http://plnkr.co/edit/rgKUsYGDo9O3tewL6xgr?p=preview
Opcion 2. A través del objeto literal y del enlace / alcance de la directiva
index.html
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<p> Directive Content</p>
<sd-items-filter selected-items="selectedItems" selected-items-changed="selectedItemsChanged(selectedItems)" items="items"> </sd-items-filter>
<P style="color:red">Selected Items (in parent controller) set to: {{selectedItemsReturnedFromDirective}} </p>
</body>
</html>
itemfilterTemplate.html
<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;"
ng-change="selectedItemsChangedDir()" ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'">
<option>--</option>
</select>
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"
}]
});
trabajo plnkr: http://plnkr.co/edit/BRvYm2SpSpBK9uxNIcTa?p=preview
Opción # 3. A través de la referencia de funciones y de la plantilla de directiva html
index.html
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<p> Directive Content</p>
<sd-items-filter selected-items="selectedItems" selected-items-changed="selectedItemsChanged" items="items"> </sd-items-filter>
<P style="color:red">Selected Items (in parent controller) set to: {{selectedItemsReturnFromDirective}} </p>
</body>
</html>
itemfilterTemplate.html
<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;"
ng-change="selectedItemsChanged()(selectedItems)" ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'">
<option>--</option>
</select>
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"
}]
});
trabajo plnkr: http://plnkr.co/edit/Jo6FcYfVXCCg3vH42BIz?p=preview
Opción # 4. A través de la referencia de funciones y del enlace / alcance de la directiva
index.html
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<p> Directive Content</p>
<sd-items-filter selected-items="selectedItems" selected-items-changed="selectedItemsChanged" items="items"> </sd-items-filter>
<P style="color:red">Selected Items (in parent controller) set to: {{selectedItemsReturnedFromDirective}} </p>
</body>
</html>
itemfilterTemplate.html
<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;" ng-change="selectedItemsChangedDir()" ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'">
<option>--</option>
</select>
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"
}]
});
trabajo plnkr: http://plnkr.co/edit/BSqx2J1yCY86IJwAnQF1?p=preview
Opción n. ° 5: a través de ng-model y enlace bidireccional, puede actualizar las variables de ámbito principal. . Por lo tanto, es posible que no necesite invocar funciones de ámbito principal en algunos casos.
index.html
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<p> Directive Content</p>
<sd-items-filter ng-model="selectedItems" selected-items-changed="selectedItemsChanged" items="items"> </sd-items-filter>
<P style="color:red">Selected Items (in parent controller) set to: {{selectedItems}} </p>
</body>
</html>
itemfilterTemplate.html
<select ng-model="selectedItems" multiple="multiple" style="height: 200px; width: 250px;"
ng-options="item.id as item.name group by item.model for item in items | orderBy:'name'">
<option>--</option>
</select>
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"
}]
});
trabajo plnkr: http://plnkr.co/edit/hNui3xgzdTnfcdzljihY?p=preview
Opción # 6: a través $watch
y$watchCollection
es vinculante items
en ambos sentidos en todos los ejemplos anteriores, si los elementos se modifican en el ámbito principal, los elementos en la directiva también reflejarían los cambios.
Si desea ver otros atributos u objetos desde el ámbito primario, puede hacerlo utilizando $watch
y $watchCollection
como se indica a continuación
html
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.9/angular.js" data-semver="1.3.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{user}}!</p>
<p>directive is watching name and current item</p>
<table>
<tr>
<td>Id:</td>
<td>
<input type="text" ng-model="id" />
</td>
</tr>
<tr>
<td>Name:</td>
<td>
<input type="text" ng-model="name" />
</td>
</tr>
<tr>
<td>Model:</td>
<td>
<input type="text" ng-model="model" />
</td>
</tr>
</table>
<button style="margin-left:50px" type="buttun" ng-click="addItem()">Add Item</button>
<p>Directive Contents</p>
<sd-items-filter ng-model="selectedItems" current-item="currentItem" name="{{name}}" selected-items-changed="selectedItemsChanged" items="items"></sd-items-filter>
<P style="color:red">Selected Items (in parent controller) set to: {{selectedItems}}</p>
</body>
</html>
script app.js
aplicación var = angular.module ('plunker', []);
app.directive('sdItemsFilter', function() {
return {
restrict: 'E',
scope: {
name: '@',
currentItem: '=',
items: '=',
selectedItems: '=ngModel'
},
template: '<select ng-model="selectedItems" multiple="multiple" style="height: 140px; width: 250px;"' +
'ng-options="item.id as item.name group by item.model for item in items | orderBy:\'name\'">' +
'<option>--</option> </select>',
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"
}]
});
Siempre puede consultar la documentación de AngularJs para obtener explicaciones detalladas sobre las directivas.