
Aby zapewnić bezpieczną reużywalność dyrektyw, twórcy Angulara postanowili wyposażyć je w izolowany zakres (isolate scope).
Isolate scope daje gwarancję, że nie wystąpią nieoczekiwane problemy związane z nadpisaniem modelu danych dyrektywy poprzez model danych nadrzędny (pochodzący z kontrolera, w którym nastąpiło użycie dyrektywy).
W poniższych przykładach zostanie użyty następujący kontroler:
var app = angular.module('plunker', []); app .controller('MainCtrl', function($scope) { $scope.person = { name: 'Joe', city: 'Warsaw', street: 'Rozana 11' }; $scope.formattedAddress = function(p) { return p.name + ', ' + p.city + ', ' + p.street; }; });
Poniższy snippet przedstawia zdefiniowanie wyizolowanego scope własnej dyrektywy.
app .directive('listPersons', function() { return { restrict: 'AE', template: '<div></div>', replace: true, scope: { } } });
Jeśliby z powyższej dyrektywy usunąć scope, kompilator zinterprerowałby relację pomiędzy kontrolerem nadrzędnym a dyrektywą, która została używa w jego obszarze, jako relację parent – child, a zatem model z parent’a (kontrolera) byłby widoczny także w child (dyrektywa).
W jaki sposób przekazywać dane do dyrektywy z izolowanym scope?
„Łączność” dyrektywy ze „światem zewnętrznym” odbywa się poprzez atrybuty dyrektywy. W poniższym przykładzie obiekt person, należący do modelu kontrolera, w której została użyta dyrektywa, jest przekazywany do wnętrza dyrektywy poprzez przypisanie do atrybutu o nazwie person-object.
<body ng-controller="MainCtrl"> <list-persons person-object="person"></list-persons> </body>
Wartości atrybutów mogą zostać przekazane na różne sposoby.
Przekazanie przez wartość (realizuje one-way data binding)
<body ng-controller="MainCtrl"> <list-persons person-name="{{ person.name }}"></list-persons> </body>
app.directive('listPersons', function() { return { restrict: 'AE', template: '<div>{{personName}}</div>', replace: true, scope: { personName: "@" // @ - oczekuje tekstu } } });
Przekazanie przez referencję (realizuje two-way data binding)
<body ng-controller="MainCtrl"> <list-persons person-object="person"></list-persons> </body>
app.directive('listPersons', function() { return { restrict: 'AE', template: '<div>{{personObject.name}}<br />{{ personObject.address}}</div>', replace: true, scope: { personObject: "=" // = - oczekuje obiektu (two-way) } } });
Przekazanie funkcji
<body ng-controller="MainCtrl"> <list-persons formatted-function="formattedAddress(aperson)" person-object="person"> </list-persons> </body>
app.directive('listPersons', function() { return { restrict: 'AE', template: '<div>{{ formattedFunction({aperson : personObject }) }}</div>', replace: true, scope: { personObject: "=", // oczekuje obiektu (two-way) formattedFunction: "&" // oczekuje funkcji } } });