Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

AngularJS, direttive per integrare plugin jQuery

Come integrare due plugin jQuesy e sfruttare AngularJS anche su stack predefiniti
Come integrare due plugin jQuesy e sfruttare AngularJS anche su stack predefiniti
Link copiato negli appunti

Nonostante AngularJS sia un framework molto potente ci sono svariati motivi per volerlo integrare con codebase pre-esistente.

Anzitutto AngularJS si occupa principalmente dell'architettura dell'applicazione, senza toccare gli aspetti di user interface quali possono essere caroselli di immagini, finestre modali e controlli di form avanzati.

In secondo luogo spesso ci troviamo a dover applicare AngularJS su stack già definiti. Il caso più semplice è dover integrare la logica client-side su un tema di Bootstrap. Un'altro è quello in cui si debba utilizzare un plugin jQuery dovendosi interfacciare con il model di un controller AngularJS.

Il grosso vantaggio in tutti questi scenari è che AngularJS è particolarmente adatto per l'integrazione in ambienti jQuery-like (inclusi quindi jQuery2 e Zepto) visto che parte delle sue API come angular.element utilizzano l'engine di jQuery quando disponibile.

Uno degli esempi migliori di questa integrazione è AngularUI che unisce AngularJS con Bootstrap 3.

In questo articolo vedremo come utilizzare due semplici plugin jQuery all'interno di un'applicazione AngularJS.

Una questione di direttive

Nell'architettura di un'applicazione AngularJS l'unico modo per interagire con il DOM è attraverso l'uso di una direttiva. È qui che dovremo indirizzarci per integrare i nostri plugin.

Nella sua forma più semplice una direttiva può essere dichiarata con la seguente sintassi:

angular.module('myApp', [])
.directive('myDirective', function () {
    return {
        restrict: 'AC',
        link: function (scope, element, attrs) {
            element.addClass('is-active');
        }
    };
});
// utilizzare come: <div my-directive></div>

L'oggetto di definizione della direttiva ha due proprietà:

Proprietà Descrizione
restrict come possiamo utilizzare la direttiva nella view. Nel nostro caso come attributo (A) oppure come classe (C).
link la funzione che va lanciata su ogni elemento DOM a cui è associata la direttiva.

Nell'esempio precedente la direttiva my-directive aggiunge una classe ad ogni elemento su cui è applicata mutuando il metodo .addClass di jQuery (Scarica l'esempio1 | guarda live).

Creare una direttiva per i tooltip

Nell'esempio seguente vedremo come utilizzare quanto visto finora per creare una direttiva per qTip2, un plugin jQuery per la realizzazione di tooltip custom.

Il nostro html di esempio sarà:

<span my-tooltip title="Testo nel tooltip">Testo nel box</span>

Per un'integrazione basilare la direttiva da definire è molto semplice:

angular.module('myApp', [])
.directive('myTooltip', function () {
    return {
        restrict: 'AC',
        link: function (scope, element, attrs) {
            element.qtip();
        }
    };
});

Scarica l'esempio 2 e guarda la direttiva in azione (live).

Che il plugin funzioni correttamente e che si integri alla perfezione con AngularJS è dimostrato dal fatto che anche utlizzando un'espressione per valorizzare l'attributo title del tag, questa viene correttamente passata al plugin.

Scarica l'esempio 3 e guarda la direttiva in azione (live).

Passare variabili di configurazione

Sebbene questa direttiva possa andare bene per un utilizzo generico, qTip2 supporta una serie di parametri di configurazione per personalizzarne gli stili ed il posizionamento.

Nella nostra direttiva passeremo questi parametri come valore dell'attributo my-tooltip:

<span my-tooltip="{position: { my: 'left center'}}" title="Testo nel tooltip">Testo nel box</span>

angular.module('myApp', [])
.directive('myTooltip', function () {
    return {
        restrict: 'AC',
        link: function (scope, element, attrs) {
            var config = scope.$eval(attrs.myTooltip);
            element.qtip(config);
        }
    };
});

Scarica l'esempio 4 e guarda la direttiva in azione (live).

Carosello di immagini

Il secondo caso che vedremo è la realizzazione di un carosello di immagini con cycle2.

Per garantire flessibilità e semplicità d'uso, dovremo sviluppare una direttiva più avanzata rispetto a quella del tooltip.

Come primo passo stamperemo un array di immagini images utilizzando le direttive ng-repeat e ng-src:

<div id="slideshow">
    <img class="slide" ng-src="{{image}}" ng-repeat="image in images" />
</div>

Quindi, come per l'esempio precedente lanceremo il plugin nella funzione link della direttiva:

angular.module('myApp', [])
.directive('mySlideshow', function () {
    return {
      restrict: 'AC',
      link: function (scope, element, attrs) {
        var config = angular.extend({
          slides: '.slide'
        }, scope.$eval(attrs.mySlideshow)); 
        setTimeout(function () {
         element.cycle(config);
        }, 0);
      }
    };
});

Di default utilizzeremo la classe slide come identificativo di ogni elemento del carosello. Questo ci permetterà di utilizzare facilmente anche contenuti testuali o misti.

Da notare che la chiamata al plugin è inserita in un timeout a zero. Questo permette di posticipare l'esecuzione del plugin dopo la fase di rendering di AngularJS, evitando così che possa partire prima che ng-repeat abbia finito il proprio ciclo.

Ecco una versione funzionante dello script (live).

Template predefinito

Una delle feature di Cycle 2 è il paginatore automatico. Per attivarlo basta inserire all'interno dello slider, il codice:

<div class="cycle-pager"></div>

Seguendo quanto fatto finora potremmo aggiungerlo nella view. Tuttavia nel nostro caso vogliamo inserirlo come feature di default per tutti gli slideshow e per farlo utilizzeremo due proprietà delle direttive di AngularJS:

Proprietà Descrizione
template permette di definire un template di default per i contenuti delle direttive.
transclude permette di ricopiare all'interno del template la parte di view contenuta originariamente nella direttiva, mantenendone inalterato lo scope.

Il codice di my-slideshow diventerà quindi:

angular.module('myApp', [])
.directive('mySlideshow', function () {
    return {
      restrict: 'AC',
      transclude: true,
      template: '<div ng-transclude></div><div class="cycle-pager"></div>',
      link: function (scope, element, attrs) {
        var config = angular.extend({
          slides: '.slide'
        }, scope.$eval(attrs.mySlideshow)); 
       setTimeout(function () {
         element.cycle(config);
        }, 0);
      }
    };
});

L'uso della direttiva ng-transclude nel template indica dove andranno inseriti i contenuti originali della view.

Ecco il risultato finale. (live).

Solo l'inizio

Queste due direttive di esempio sono solo il punto di inizio per comprendere le potenzialità dell'integrazione di plugin jQuery nel rispetto degli standard di AngularJS.

In base alle API di ogni plugin, si possono sfruttare caratteristiche come, ad esempio, il $watch su una proprietà per gestire dinamicamente il contenuto visualizzato, oppure alterare valori dello scope esterno utilizzando la gestione 2-way dell'attributo scope.

Per approfondire ulteriormente:

Ti consigliamo anche