AngularJS-direktiivi – Scopes

Aion puhua AngularJS-direktiiveistä ja erityyppisistä scopeista, joita voidaan käyttää. On 3 pääasiallista tapaa, joilla scope voidaan välittää direktiiville kutsuvasta näkymästä (HTML):

  • Default Scope
  • Inherited Scope
  • Isolated Scope

Ja isolated scope voi itsessään olla:

  • Oneway
  • Twoway
  • Method Reference

Default Scope

Tässä tyypissä ulommasta näkymästä tuleva scope vain valuu direktiiviin. Toisin sanoen, laajuus välitetään ”viittauksena” direktiiviin. Kaikki scope-tiedot ovat välittömästi käytettävissä direktiivin sisällä kulutettavaksi. Samoin kaikki direktiivin sisällä scopeen tehdyt muutokset heijastuvat välittömästi kutsuvaan näkymään.

näkymään ja direktiiviin sidottu vis scope

Tämä saavutetaan määrittelemällä direktiivin määrittelyssä scope as

scope: false // false is the default value

.

Oheisessa esimerkissä ’nimi’ on lennätetty direktiiviin ja kaikki tehdyt muutokset heijastuvat välittömästi sen ulkopuolelle. Koska scope on asetettu true:ksi, direktiivi saa scope:n kutsujakseen. Nyt kaikki direktiivin nimelle tehdyt muutokset heijastuvat välittömästi ’MyController’-kontrolleriin.

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 on @ https://jsfiddle.net/madhanganesh/830rn1fm/

Peritty scope

Tässä tyypissä uusi scope periytyy view scopeista. Javascriptissä objektit periytyvät prototyyppisen periytymisen avulla. Tämä skenaario on esitetty alla olevassa kaaviossa:

Tämä saavutetaan määrittelemällä soveltamisala muotoon

scope: true

direktiivin määrittelyssä.

Alhaalla olevassa esimerkissä voit kokeilla vaihtaa nimeä direktiivissä. Tämä muutos ei heijastu ulospäin ’perityn’ laajuuden vuoksi. Arvo kulkee vain sisällä, mutta mikä tahansa muutos johtaa kopioon direktiiviin eikä heijastu ulospäin.

Alhaalla olevassa live-esimerkissä näet, että ’nimi’ lentää direktiiviin; mutta direktiivissä tehty muutos ei heijastu ulospäin.

Alhaalla olevassa esimerkissä direktiivin soveltamisalalle on annettu arvo true. Tämä tarkoittaa, että direktiiville luodaan scope, joka ”periytyy” controllerin scopeista. Javascriptin prototyyppisten periytymissääntöjen mukaan johdettu objekti (direktiivin scope) viittaa samoihin ominaisuuksiin kuin vanhemman objektin (controllerin scope). Kaikki kontrolleriin tehdyt muutokset heijastuvat direktiiviin, kunnes direktiivin ”name”-ominaisuuteen tehdään muutos. Tällöin direktiiville luodaan uusi objekti ja muutokset ovat toisistaan läpinäkymättömiä.

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

Tämässä scope-määrittelyssä direktiivi saa riippumattoman scope:n, joka ei vastaanota tai lähetä takaisin dataa sisältävään näkymään.

Tämä saavutetaan määrittelemällä direktiivin määrittelyssä scope as

scope: {}

.

Oheisessa esimerkissä eristetty scope saavutetaan välittämällä direktiiviin tyhjä objekti {}.

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

Live fiddle on @ https://jsfiddle.net/madhanganesh/7d37w08e/

Isoleerattu scope on oikeastaan muutakin kuin se, että se rajoittaa täysin minkä tahansa datan välittämistä direktiiviin (ja sieltä pois). Toisessa ääripäässä voit rajoittaa dataa täysin kuten yllä olevassa esimerkissä. On kuitenkin mahdollista siirtää yksi tai useampi attribuutti direktiiviin ja kaapata ne direktiivin soveltamisalaksi. Joustavuus tulee tavasta, jolla välitettyä attribuuttia tulkitaan direktiivin sisällä. Direktiiviin välitetty attribuutti voidaan tulkita jollakin seuraavista kolmesta tavasta:

  • kuin oneway, joka arvioidaan ennen välittämistä direktiiviin
  • kuin twoway viittaus omaisuuteen kutsutussa laajuudessa
  • kuin viittaus metodiin kutsutussa laajuudessa

Ilmoitus

Direktiivin kutsuja voi välittää eksplisiittisesti arvon alla olevan kuvan mukaisesti:

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

Tapa, jolla se kaapataan direktiivin sisällä, on:

scope: {
name: '@name'
}

@-symboli kertoo angularille, että se pitää name-attribuuttia lausekkeena ja arvioi sen ennen arvon antamista text-ominaisuudelle. Koska lauseke evaluoidaan, kyseessä on yksisuuntainen sidonta, eikä direktiivin sisällä tehty arvon päivitys heijastu direktiivin ulkopuolelle.

Oheisessa esimerkissä näet, että name-ominaisuus välitetään direktiiviin. Tämä on lauseke, joka evaluoidaan ja osoitetaan direktiivin eristettyyn scopeen. Tämä tarkoittaa, että arvo ”Jack” evaluoidaan ja osoitetaan tekstinä direktiivin sisällä.

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/

Koska name on tekstinä direktiivissä, muutokset ovat paikallisia direktiivissä eikä mitään jaeta vanhemman kontrollerin kanssa.

Kaksisuuntainen (viittaus omaisuuteen)

Direktiivin kutsuja voi välittää direktiiville viittauksen omaisuuteen, kuten:

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

Tapa, jolla se kaapataan direktiivin sisällä, on:

scope: {
name: '=name'
}

=-symboli käskee angularia pitämään name-attribuuttia viittauksena tiettyyn omaisuuteen kutsuvassa scopeissa. Arvo siis välitetään direktiiviin ja kaikki attribuuttiin tehdyt muutokset heijastuvat välittömästi ulospäin.

Oheisessa esimerkissä näet, että name-ominaisuus välitetään direktiiviin. Tämä on viittaus name-ominaisuuteen vanhempien scopeissa.

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 on @ https://jsfiddle.net/madhanganesh/o74nvcj3/1/

Koska name on viittaus ominaisuuteen ohjaimessa, kaikki muutokset kummallakin puolella heijastuvat molempiin.

Viittaus metodiin

Tapa, jolla se siirretään kutsuvasta näkymästä on:

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

Tapa, jolla se kaapataan direktiivin sisällä on:

scope: {
nameFn: '& nameFn'
}

& symboli kertoo angularille, että se pitää nameFn-attribuuttia viittauksena tiettyyn kutsuvan scopein metodiin. Tämä metodi voidaan sitten tarvittaessa suorittaa direktiivin sisältä.

Oheisessa esimerkissä nameFn-ominaisuus on metodi, jonka viite välitetään direktiivin sisällä. Tämä funktio suoritetaan direktiivin sisältä, mutta se arvioidaan kutsuvan scope:n kontekstissa.

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/

Yhteenveto

Kuten huomaat direktiivin scope on melko tyhjentävä, alla oleva yhteenveto kiteyttää mahdollisuudet ja niiden merkityksen.

  • Oletusarvo : Direktiivi saa saman scope:n kuin sen sisältävä näkymä
  • Peritty: Direktiivi saa laajuuden, joka periytyy sisältävän näkymän laajuudesta
  • Isolated: Direktiivi saa soveltamisalan, joka on riippumaton sisältävästä näkymästä

Ja eristetyn soveltamisalan sisällä on 3 vaihtoehtoa:

Oneway : Direktiivin attribuuttia pidetään lausekkeena ja se arvioidaan ennen kuin se osoitetaan direktiivin eristetyn soveltamisalan tiettyyn ominaisuuteen

.