Własna dyrektywa – izolowany scope

angular-js-firebase

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
        }
    }
});

 

 

 

 

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *