Direktivy AngularJS – Rozsahy

Mám v úmyslu hovořit o direktivách AngularJS a různých typech rozsahů, které lze použít. Existují 3 hlavní způsoby, jak lze direktivě předat obor z vyvolávajícího zobrazení (HTML):

  • Výchozí obor
  • Zděděný obor
  • Izolovaný obor

A izolovaný obor může být sám o sobě:

  • Oneway
  • Twoway
  • Method Reference

Default Scope

V tomto typu se scope z vnějšího pohledu jen přelije do směrnice. Jinak řečeno, obor se předává jako „reference“ do směrnice. Všechna data z rozsahu budou v rámci direktivy okamžitě k dispozici ke spotřebování. Stejně tak jakákoli změna provedená v rámci směrnice se okamžitě projeví ve vyvolávajícím pohledu.

pohled a směrnice vázané vis scope

Toho je dosaženo zadáním scope jako

scope: false // false is the default value

v definici směrnice.

V níže uvedeném příkladu se ‚name‘ vlévá do direktivy a každá provedená změna se okamžitě projeví mimo ni. Protože je obor nastaven jako true, dostane direktiva obor jako její volající. Nyní se jakákoli změna provedená ve jménu v direktivě okamžitě projeví v kontroléru ‚MyController‘.

var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = "Jack";
});// usage: <div upper-case/></div>
myApp.directive('upperCase', function() {
return {
scope: false,
template: 'Name: <input ng-model="name"></input>'
}
});

Živý fiddle je @ https://jsfiddle.net/madhanganesh/830rn1fm/

Zděděný scope

V tomto typu je nový scope zděděný z view scope. V jazyce Javascript se objekty dědí pomocí prototypové dědičnosti. Tento scénář je znázorněn na diagramu níže:

Toho se dosáhne tak, že se v definici směrnice uvede obor jako

scope: true

.

V příkladu níže můžete zkusit změnit název ve směrnici. Tato změna se neprojeví navenek kvůli ‚zděděnému‘ oboru. Hodnota proudí pouze dovnitř, ale jakákoli změna bude mít za následek kopii pro direktivu a neprojeví se vně.

V živém příkladu níže můžete vidět, že ‚name‘ proudí do direktivy; ale změna provedená v direktivě se neprojeví vně.

V příkladu níže je oboru direktivy dána hodnota true. To znamená, že pro direktivu je vytvořen obor, který „dědí“ z oboru kontroléru. Podle prototypových pravidel dědičnosti javascriptu se odvozený objekt (scope směrnice) odkazuje na stejné vlastnosti rodičovského objektu (scope kontroléru). Veškeré změny provedené v controlleru se projeví v direktivě, dokud není provedena změna vlastnosti „name“ v direktivě. V tu chvíli je pro direktivu vytvořen nový objekt a změny jsou vzájemně neprůhledné.

var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = "Jack";
});// usage: <div upper-case/></div>
myApp.directive('upperCase', function() {
return {
scope: true,
template: 'Name: <input ng-model="name"></input>'
}
});

Živý fiddle je @ https://jsfiddle.net/madhanganesh/57sb6yg8/

Izolated Scope

V tomto typu definice scope získá direktiva nezávislý scope, který nepřijímá ani neposílá zpět žádná data do obsahujícího view.

Toho se dosáhne tak, že se v definici směrnice uvede rozsah jako

scope: {}

.

V níže uvedeném příkladu je izolovaného oboru dosaženo tak, že se direktivě předá prázdný objekt {}.

var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = "Jack";
});// usage: <div upper-case/></div>
myApp.directive('upperCase', function() {
return {
scope: {},
template: 'Name: <input ng-model="name"></input>'
}
});

Živý obor je @ https://jsfiddle.net/madhanganesh/7d37w08e/

Izolovaný obor je ve skutečnosti více než úplné omezení jakýchkoli dat předávaných do (a z) direktivy. Na jednom konci spektra můžete data zcela omezit, jak ukazuje výše uvedený příklad. Je ale možné předat direktivě jeden nebo více atributů a zachytit je jako obor pro danou direktivu. Flexibilita spočívá ve způsobu interpretace předaného atributu uvnitř direktivy. Atribut předaný direktivě může být interpretován jedním ze tří způsobů:

  • jako jednosměrný, který se vyhodnotí před předáním direktivě
  • jako dvoucestný odkaz na vlastnost v oboru volání
  • jako odkaz na metodu v oboru volání

Výraz

Volající direktivy může explicitně předat hodnotu, jak je uvedeno níže:

<div my-directive name='{{name}}' />
// an expression is passed to the directive

Způsob zachycení uvnitř směrnice je:

scope: {
name: '@name'
}

@ symbol říká modulu angular, aby atribut name považoval za výraz a vyhodnotil jej před přiřazením hodnoty vlastnosti text. Protože se výraz vyhodnocuje, jedná se o jednosměrnou vazbu a jakákoli aktualizace provedená na hodnotě uvnitř direktivy se neprojeví navenek.

V příkladu níže vidíte, že vlastnost name je předána direktivě. Jedná se o výraz, který je vyhodnocen a přiřazen do izolovaného oboru směrnice. To znamená, že hodnota „Jack“ je vyhodnocena a přiřazena jako text uvnitř direktivy.

var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = 'Jack';
});
// usage: <div my-directive name='{{name}}' />
myApp.directive('upperCase', function() {
return {
scope: {
name: '@name'
},
template: 'Name: <input ng-model="name"></input>'
}
});

Živý fiddle je @ https://jsfiddle.net/madhanganesh/ybzcryt0/4/

Protože name je text v direktivě, změny jsou lokální pro direktivu a nic se nesdílí s nadřazeným kontrolérem.

Dvojsměrný (odkaz na vlastnost)

Volající direktivy může direktivě předat odkaz na vlastnost, jako například:

<div my-directive name='data.name' />
// a property reference to the directive

Způsob zachycení uvnitř direktivy je:

scope: {
name: '=name'
}

= symbol říká angularu, aby atribut name považoval za odkaz na konkrétní vlastnost volajícího oboru. Hodnota je tedy předána do direktivy a jakákoli změna provedená na atributu se okamžitě projeví vně.

V příkladu níže vidíte, že vlastnost name je předána do direktivy. Jedná se o odkaz na vlastnost name v nadřazeném oboru.

var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = 'Jack';
});
myApp.directive('upperCase', function() {
return {
scope: {
name: '=name'
},
template: 'Name: <input ng-model="name"></input>'
}
});

Živý fiddle je @ https://jsfiddle.net/madhanganesh/o74nvcj3/1/

Protože name je odkaz na vlastnost v kontroléru, jakákoli změna na obou stranách se promítne do obou.

Reference na metodu

Způsob předání z volajícího pohledu je:

<div my-directive nameFn="getName()" />
// a method reference is passed to the directive

Způsob zachycení uvnitř směrnice je:

scope: {
nameFn: '& nameFn'
}

& Symbol říká angularu, aby atribut nameFn považoval za odkaz na konkrétní metodu volajícího oboru. Tato metoda pak může být v případě potřeby spuštěna zevnitř směrnice.

V níže uvedeném příkladu vidíte, že vlastnost nameFn je metoda, jejíž odkaz je předán uvnitř směrnice. Tato funkce se provede z oboru směrnice, ale vyhodnotí se v kontextu volajícího oboru.

var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = 'Jack';
$scope.getName = function() {
return $scope.name;
}
});
myApp.directive('upperCase', function() {
return {
scope: {
nameCb: '&name'
},
//template: 'Name: <input ng-model="nameFn()"></input>'
template: 'Name: {{textCb()}}'
}
});

Živá hříčka je @ https://jsfiddle.net/madhanganesh/6w4msr5k/1/

Souhrn

Jak vidíte, rozsah směrnice je poměrně vyčerpávající, níže uvedený souhrn zachycuje možnosti a jejich význam.

  • Výchozí : Směrnice dostane stejný rozsah jako její obsahující pohled
  • Dědičný: Směrnice dostane rozsah, který je zděděný z rozsahu obsahujícího pohledu
  • Izolovaný: Směrnice získá obor, který je nezávislý na oboru obsahujícího zobrazení

A v rámci izolovaného oboru existují 3 možnosti:

Oneway : Atribut směrnice je považován za výraz a je vyhodnocen před přiřazením konkrétní vlastnosti izolovaného oboru směrnice