AngularJS irányelv – hatókörök
Scopes in AngularJS Directives
Az AngularJS irányelvekről és a különböző használható hatókörökről szeretnék beszélni. A hatókör 3 fő módon adható át a direktívának a hívó nézetből (HTML):
- Default Scope
- Inherited Scope
- Isolated Scope
Az izolált hatókör pedig maga lehet:
- Oneway
- Twoway
- Method Reference
Default Scope
Ebben a típusban a hatókör a külső nézetből csak átfolyik a direktívába. Másképpen fogalmazva, a hatókör “hivatkozásként” kerül átadásra a direktívának. Az összes hatóköradat azonnal elérhető lesz a direktíván belül a fogyasztásra. Hasonlóképpen, a hatókörben a direktíván belül végrehajtott bármilyen változás azonnal megjelenik a hívó nézetben.
Ez úgy érhető el, hogy a hatókör
scope: false // false is the default value
ként van megadva a direktíva definíciójában.
A lenti példában a ‘name’ belerepül a direktívába, és minden elvégzett módosítás azonnal megjelenik a direktíván kívül. Mivel a hatókör igaznak van beállítva, a direktíva megkapja a hatókörét, mint a hívója. Most a direktívában a névben végrehajtott bármilyen változás azonnal tükröződik a ‘MyController’ vezérlőben.
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>'
}
});
Live fiddle is @ https://jsfiddle.net/madhanganesh/830rn1fm/
Inherited Scope
Ebben a típusban egy új scope öröklődik a view scope-ból. A Javascriptben az objektumok prototípusos örökléssel öröklődnek. Ez a forgatókönyv az alábbi ábrán látható:
Ez úgy érhető el, hogy a scope-ot
scope: true
ként adjuk meg a direktíva definíciójában.
Az alábbi példában megpróbálhatjuk megváltoztatni a nevet a direktívában. Ez a változás az “örökölt” hatókör miatt nem fog kívülről tükröződni. Az érték csak belül áramlik, de bármilyen változás másolatot eredményez a direktívára, és nem fog tükröződni kívülről.
A lenti élő példában látható, hogy a ‘név’ berepül a direktívába; de a direktívában végrehajtott változás nem fog tükröződni kívülről.
A lenti példában a direktíva hatókörét true értékkel látjuk el. Ez azt jelenti, hogy egy olyan hatókör jön létre a direktíva számára, amely “örökli” a vezérlő hatókörét. A javascript prototípusos öröklési szabályai szerint a származtatott objektum (a direktíva hatókör) a szülőobjektum (a vezérlő hatókörének) azonos tulajdonságaira hivatkozik. A vezérlőn végrehajtott bármilyen változtatás tükröződik a direktívában, amíg a direktíva “name” tulajdonságában nem történik változás. Ekkor egy új objektum jön létre a direktívához, és a változások átláthatatlanok egymástól.
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>'
}
});
Live fiddle is @ https://jsfiddle.net/madhanganesh/57sb6yg8/
Isolated Scope
Egy ilyen típusú scope definícióban a direktíva egy független scope-ot kap, amely nem kap vagy küld vissza adatokat a tartalmazó view-nak.
Ez úgy érhető el, hogy a hatókör
scope: {}
ként van megadva a direktíva definíciójában.
Az alábbi példában az izolált hatókör úgy érhető el, hogy egy üres {} objektumot adunk át a direktívának.
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>'
}
});
Az élő fiddle @ https://jsfiddle.net/madhanganesh/7d37w08e/
Az izolált hatókör valójában többet jelent, mint a direktívába (és onnan) átadható adatok teljes korlátozása. A spektrum egyik végén teljesen korlátozhatod az adatokat, ahogy a fenti példában látható. De lehetséges egy vagy több attribútumot átadni a direktívának, és azokat a direktíva hatóköreként rögzíteni. A rugalmasságot az adja, ahogyan az átadott attribútumot a direktíván belül értelmezik. A direktívának átadott attribútumot a következő háromféleképpen lehet értelmezni:
- egyirányúként, amely a direktívának való átadás előtt kiértékelésre kerül
- kétirányúként a hívó hatókörben lévő tulajdonságra való hivatkozásként
- a hívó hatókörben lévő metódusra való hivatkozásként
Kifejezés
A direktíva hívója kifejezetten átadhat egy értéket, ahogy az alább látható:
<div my-directive name='{{name}}' />
// an expression is passed to the directive
Az irányelvben való rögzítés módja a következő:
scope: {
name: '@name'
}
@ szimbólum azt mondja az angularnak, hogy a name attribútumot tekintse kifejezésnek és értékelje ki, mielőtt az értéket hozzárendelné a text tulajdonsághoz. Mivel a kifejezés kiértékelésre kerül, ez egy egyirányú kötés, és a direktíván belül az értéken végzett bármilyen frissítés nem fog tükröződni kívülről.
A lenti példában látható, hogy a name tulajdonságot átadjuk a direktívának. Ez egy kifejezés, amely kiértékelődik és hozzárendelődik a direktíva elszigetelt hatóköréhez. Ez azt jelenti, hogy a “Jack” érték kiértékelésre és hozzárendelésre kerül, mint szöveg a direktíván belül.
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>'
}
});
Live fiddle is @ https://jsfiddle.net/madhanganesh/ybzcryt0/4/
Miatt, hogy a name egy szöveg a direktívában, a változások a direktívában lokálisak, és semmi sem kerül megosztásra a szülő vezérlővel.
Kétirányú (hivatkozás tulajdonságra)
A direktíva hívója átadhat egy tulajdonságra való hivatkozást a direktívának, mint:
<div my-directive name='data.name' />
// a property reference to the directive
A direktíván belüli rögzítés módja:
scope: {
name: '=name'
}
= szimbólum azt mondja az angularnak, hogy a name attribútumot tekintse a hívó scope konkrét tulajdonságára való hivatkozásnak. Tehát az értéket átadja a direktívának, és az attribútumon végrehajtott bármilyen változás azonnal tükröződik kívülről.
A lenti példában látható, hogy a name tulajdonságot átadja a direktívának. Ez egy hivatkozás a szülői hatókörben lévő name tulajdonságra.
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>'
}
});
Live fiddle is @ https://jsfiddle.net/madhanganesh/o74nvcj3/1/
Mert a name egy hivatkozás a vezérlőben lévő tulajdonságra, bármelyik oldalon bekövetkező változás mindkét oldalon tükröződik.
Hivatkozás a metódusra
Az átadás módja a hívó nézetből:
<div my-directive nameFn="getName()" />
// a method reference is passed to the directive
Az átadás módja a direktíván belül:
scope: {
nameFn: '& nameFn'
}
& A szimbólum azt mondja az angularnak, hogy a nameFn attribútumot tekintse hivatkozásnak a hívó hatókör konkrét metódusára. Ezt a metódust aztán szükség esetén a direktíván belülről lehet végrehajtani.
A lenti példában látható, hogy a nameFn tulajdonság egy metódus, amelynek hivatkozása a direktíván belül kerül átadásra. Ez a függvény a direktívából kerül végrehajtásra, de a hívó hatókör kontextusában kerül kiértékelésre.
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()}}'
}
});
Live fiddle is @ https://jsfiddle.net/madhanganesh/6w4msr5k/1/
Summary
Amint látható a direktíva hatókör elég kimerítő, az alábbi összefoglaló a lehetőségeket és azok jelentését ragadja meg.
- Default : A direktíva ugyanazt a hatókört kapja, mint az azt tartalmazó view
- Inherited: Az irányelv a tartalmazó nézet hatóköréből örökölt hatókörét kapja
- Elszigetelt: A direktíva a tartalmazó nézettől független hatókörbe kerül
Az elkülönített hatókörön belül 3 lehetőség van:
Oneway : A direktíva attribútumot kifejezésnek tekintik és kiértékelik, mielőtt hozzárendelnék a direktíva elkülönített hatókörének adott tulajdonságához
.