Sommario
< Home
Stampa

Una applicazione Javascript completa

Introduzione

Riepiloghiamo qui i principali elementi di Javascript visti nelle precedenti lezioni

Abbiamo quindi una visione di insieme di Javascript tale da permetterci di creare applicazioni anche complesse, che interagiscono sia con l’utente che con servizi internet, che manipolano dati in asincrono, e che fanno uso di programmazione funzionale.

Struttura generale di una applicazione

Il modello evento-azione-reazione resta il principio che deve guidare lo sviluppo dell’applicazione, ma dobbiamo fare attenzione a due aspetti: l’applicazione può essere asincrona, quindi la reazione potrebbe avvenire in una callback asincrona, e in secondo luogo l’applicazione potrebbe essere scomponibile in componenti indipendenti tra loro.

Per realizzare una applicazione web utilizzeremo una struttura standard che comprende queste sezioni:

SezioneEsempio
Dichiarazione di tutti gli oggetti che eseguono il binding del DOM const div = document.getElementById("myDiv");
Dichiarazione di eventuali templateconst template = "<td>%NOME</td>";
Dichiarazione di eventuali variabili dati (dette variabili di “modello”)let list = [];
Funzione render, che prende i dati e ricrea una sezione di html con i dati “trasformati” in html.const render = () => {  
let html = "";
list.forEach((element) => {
...
}  
div.innerHTML = html;
}
Gestione eventi utente, dove andiamo a gestire eventuali input utente o altre azioni.button.onclick = () => {...}
Chiamate remoteconst getData = (callback) => {
  fetch(url, options).then(callback);
}

E’ importante rivedere bene la struttura generale dell’applicazione:

– tutto il codice è nell’applicazione Javascript, nell’HTML (sebbene sia tecnicamente possibile) non si inserisce mai codice Javascript, per tenere rigidamente separati gli ambiti;

– deve essere previsto un oggetto (o più oggetti) che contiene i dati;

– la render trasforma questo oggetto in html che viene “iniettato” in pagina;

– la gestione di eventi utenti porta ad una azione che agisce solo sui dati ed eventualmente esegue una fetch per comunicare con servizi internet;

– le callback eseguite al termine della fetch vanno a modificare i dati, oppure se serve eseguono nuove fetch (ad esempio per reperire informazioni da altri servizi);

– infine, quando i dati sono pronti per essere visualizzati, viene eseguita una render della sola parte HTML da aggiornare;

Possiamo rappresentare il ciclo di vita dell’applicazione col seguente diagramma:

L’avvio iniziale dell’applicazione porta ad uno stato “pronto” in cui l’applicazione attende eventi utente per cui ha registrato delle azioni. L’azione può comprendere una o più fetch e quindi una modifica dei dati dell’applicazione stessa. Infine, dopo che i dati sono modificati viene eseguita una nuova render, che aggiorna la pagina html con la nuova visualizzazione.

Qui sotto un esempio di una semplice applicazione che mostra questo flusso. Si tratta di una applicazione con un html molto semplice che mostra una form con un campo di input, un pulsante ed una tabella con due colonne. L’applicazione riceve in input una parola, la ricerca su un servizio che ne restituisce un JSON contenente il significato, e poi alla tabella viene aggiunta la nuova parola col suo significato.

Qui l’HTML:

<html>
   <head>
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
      <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js" integrity="sha384-BBtl+eGJRgqQAUMxJ7pMwbEyER4l1g+O15P+16Ep7Q9Q+zqX6gSbd85u4mG4QzX+" crossorigin="anonymous"></script>
   </head>
   <body class="container">
      <div class="row">
         <label for="inputWord">Inserisci il valore</label>
         <input id="inputWord" type="text">
      </div>
      <div class="row">
         <button type="button" id="submit" >Submit</button>
      </div>
      <div class="row mt-5">
         <table id="tabella" class="table">

         </table>
      </div>
      <script src="index.js" ></script>
   </body>
</html>

Qui il Javascript:

const inputWord = document.getElementById("inputWord");
const submit = document.getElementById("submit");
const table = document.getElementById("tabella");

const template = "https://api.dictionaryapi.dev/api/v2/entries/en/%WORD";
const htmlTemplate = `<tr><td>%NAME</td><td>%VALUE</td></tr>`;
const header = `<tr><th>Word</th><th>Meaning</th></tr>`;

const list = [];

const render = () => {  
  let html = "";
  list.forEach((element) => {
    let row = htmlTemplate.replace("%NAME", element[0]);
    row = row.replace("%VALUE", element[1]);
    html += row;
  })
  table.innerHTML = header + html;
}

submit.onclick = () => {
  const word = inputWord.value;
  let newUrl = template.replace("%WORD", word);
  fetch(newUrl)
  .then(response => response.json())
  .then(data => {
    console.log(data);
    list.push([word, data[0].meanings[0].definitions[0].definition]);
    render();
  });
}