In alcune situazioni, nella definizione di una direttiva potremmo la avere necessità di eseguire del codice JavaScript per effettuare delle operazioni preliminari o per definire comportamenti non descrivibili tramite il solo template.
Consideriamo ad esempio il caso in cui vogliamo inserire una scritta nella select della nostra direttiva con l'invito "Seleziona una città"
come primo elemento. In questo caso possiamo sfruttare la proprietà link
della direttiva.
A questa proprietà è possibile assegnare una funzione che verrà eseguita immediatamente prima del rendering della direttiva, quindi possiamo definire le eventuali inizializzazioni che si rendono necessarie per il nostro caso. Il seguente codice mostra come possiamo aggiungere la voce Seleziona una città
alla select
della nostra direttiva:
angular.module("myApp", [])
.directive("mySelectCity", function() {
return {
restrict: "E",
templateUrl: "/mySelectCityTemplate.html",
scope: {
cityList: "=",
cityDisplayProperty: "@",
emptyAction: "&"
},
link: function(scope, element, attributes) {
var firstElement = {};
firstElement[scope.cityDisplayProperty] = "Seleziona una città";
if (scope.cityList.length > 0) {
scope.cityList.splice(0, 0, firstElement);
scope.selectedItem = firstElement;
}
}
};
});
La proprietà link
Abbiamo associato alla proprietà link della direttiva una funzione che crea un oggetto che rappresenta la voce che vogliamo inserire e, nel caso in cui ci sia almeno un elemento nell'elenco delle città, aggiunge questo nuovo elemento in cima all'elenco e lo imposta come elemento selezionato.
Possiamo notare come la funzione di link preveda tre parametri:
- lo scope della direttiva;
- l'elemento del DOM a cui è associata la direttiva;
- l'elenco degli attributi associati ad essa.
Nel nostro esempio abbiamo sfruttato soltanto il primo parametro. In generale possiamo sfruttare questi tre parametri per gestire al meglio l'inizializzazione della nostra direttiva. Ricordiamo che la direttiva è l'unico componente Angular in cui siamo autorizzati a manipolare il DOM.
Infatti, se l'uso del template non è sufficiente per definire l'interfaccia grafica della nostra direttiva o per qualche motivo abbiamo la necessità di gestire il DOM da codice, la funzione associata alla proprietà link
è il posto ideale per fare questo tipo di interventi.
Ad esempio, al posto di inserire un elemento nelle option
della select
per la voce Seleziona una città
possiamo aggiungere un paragrafo al markup della nostra direttiva nel seguente modo:
link: function(scope, element, attributes) {
element.prepend("<p>Seleziona una città</p>");
}
Come possiamo vedere, abbiamo sfruttato il parametro element per aggiungere un paragrafo HTML con il suo contenuto prima della nostra select
. Per far questo abbiamo utilizzato il metodo prepend()
. Il parametro element
è un elemento del DOM arricchito delle funzionalità di jqLite. Infatti Angular include una versione leggera di jQuery (jqLite, appunto) per consentire la manipolazione del DOM.
Il terzo parametro passato alla funzione link
della direttiva è un oggetto che consente di accedere agli attributi dell'elemento HTML a cui è essa è associata. I vari attributi sono accessibili come proprietà dell'oggetto. Ad esempio, se la nostra direttiva è usata nel seguente modo all'interno di una view:
<my-select-city
city-list="elencoCitta"
city-display-property="nome"
empty-action="svuotaCitta()">
</my-select-city>
Il parametro attributes
il parametro attributes
della funzione link
avrà tre proprietà:
attributes.cityList
,attributes.cityDisplayProperty
,attributes.emptyAction
.
Apparentemente potrebbe sembrare una duplicazione delle variabili dello scope isolato, ma in realtà ci sono delle significative differenze.
Innanzitutto l'oggetto attributes
è sempre disponibile, anche quando una direttiva non ha uno scope isolato. In secondo luogo, anche in presenza dello scope isolato, il parametro attributes
ci consente di accedere anche ad attributi che non sono mappati su variabili di scope.
Infine, il valore delle proprietà dell'oggetto attributes
è rappresentato dal valore letterale assegnato agli attributi, senza alcuna interpretazione. Cioè, il loro valore è costituito dalle stringhe assegnate agli attributi nella view.