Molto spesso nei nostri progetti c’è la necessità di passare dati fra diversi controller; una delle soluzioni che ho visto adottare spesso è quella di utilizzare emit / broadcast dalla parte di chi il dato lo vuole condividere e registrare uno o più listener dalla parte dei controller che devono essere notificati di questo nuovo dato.

Il tipo di approccio sopra pò presentare qualche criticità, sia nel capire il codice per chi non l’ha scritto (e anche per chi l’ha scritto, se passa molto tempo) sia per la sua implementazione; se abbiamo il controller A che deve condividere il dato xx con il controller B ed entrambi possono modificare xx, ci si trova  a dover creare un emit sia sua A sia su B e, allo stesso modo, un listener sia su A sia su B. Infine, una parola anche sulla testabilità: con tale approccio si può testare, ma anche la parte di testing diventa più difficoltosa e poco lineare.

Dopo questa premessa, vi propongo un approccio diverso, sfruttando un service per scambiare i dati e mantenere lo stato; tutto questo è possibile perchè in Angular i service sono singleton, quindi una volta istanziati dal container DI la stessa istanza viene passata nel costruttore di ogni oggetto che ne faccia richiesta tramite dipendenza nel costruttore.

Nel codice allegato (che trovate alla fine) c’è un esempio funzionante di quanto vi sto dicendo; ve lo descrivo brevemente di seguito.

Abbiamo una semplice pagina con una input box, un pulsante ed una lista.

L’input box e il pulsante sono controllati dal controller First mentre la lista dal controller Second (si, lo so, poca fantasia… ); l’utente può inserire una stringa non vuota nell’input e, premendo il pulsante, aggiungerla alla lista che viene poi mostrata da Second.

Entrambi i controller First e Second hanno una dipendenza verso il service myService (sempre molta fantasia…), che mantiene una collezione delle stringhe.
In particolare i diversi attori:

FirstController

  1. Ha la proprietà nuovoDato, in bind con la input
  2. Espone il metodo addDato in bind con il pulsante; quando premuto, chiama il metodo addDato di myService, passando come argomento nuovoDato

SecondController

  1. Espone la funzione dati, in bind con l’elemento <li> tramite la direttiva ngRepeat. La funzione dati, al suo interno, richiama il metodo getList di myService, che ritorna la collezione di stringhe

MyService

  1. Ha la proprietà privata myData che mantiene al suo interno la lista delle stringhe (si tratta di un array, inizializzata con già un dato al suo interno “Dato già presente…”)
  2. Espone il modo addDato, che prende in ingresso una stringa e la aggiunge all’array myData
  3. Espone il metodo getList che ritorna la lista delle strighe (array myData)

Il tutto è molto semplice, come potete vedere, ma anche lineare; un unico punto in cui il dato viene mantenuto e aggiornato; i controller non fanno altro che chiamare i metodi del servizio senza doversi preoccupare di notifiche e gestione di eventi.

Tutto il codice client è scritto in TypeScript

Soluzione Visual Studio 2015

Share Button