Dart: Web Components

Di - 15 December 2012 - in

Nelle scorse settimane abbiamo iniziato a vedere come funzionano le applicazioni web in Dart e nell’articolo di oggi tratteremo argomenti molto interessanti per questo tipo di applicazioni: web components e Model-driven Views (MDV).

Quando parliamo di Model-driven views ci riferiamo ad un insieme di tecniche che ci consentono di generare documenti sulla base di templates e sorgenti di dati; la programmazione model-driven, sulla quale si basano, fra gli altri, i framework web AngularJS, BackboneJS e la piattaforma di blogging Jekyll, ci consente di creare modelli che hanno una sintassi tipo:

<h1>{{ titolo }}</h1>

dove il tag {{ titolo }} sarà sostituito al momento della compilazione con il valore della variabile titolo nella sorgente di dati, che nel nostro caso è Dart.

I vantaggi di questo tipo di programmazione sono molti, il primo fra tutti è quello di automatizzare il processo di abbinamento di dati e di modelli all’interfaccia grafica incrementando notevolmente la leggibilità del codice.

Un altro vantaggio è la sincronizzazione fra dati, modelli e interfaccia: al cambiamento di una variabile all’interno del codice saranno infatti aggiornati tutti gli elementi dell’interfaccia che stanno utilizzando quel valore.

Vediamo subito in cosa consiste un’applicazione in Dart basta sul concetto di MDV e introduciamo la libreria Web UI (ex Web Components); apriamo Dart Editor, creiamo una nuova web application, googlab, e aggiungiamo la dipendenza web_ui: any nel file pubspec.yaml :

name:  googlab
description:  Una descrizione qualsiasi

dependencies:
  web_ui: any

Il comando pub install restituirà nella console:

Running pub install ...
Resolving dependencies...
Downloading web_ui 0.2.10+1...
Downloading logging 0.2.8+2...
Downloading js 0.0.13...
Downloading html5lib 0.2.2...
Downloading args 0.2.8+2...
Downloading meta 0.2.8+2...
Dependencies installed!

A conferma della corretta installazione delle dipendenze possiamo controllare se nella directory packages sono presenti args, html5lib , web_ui, etc.

Ora abbiamo bisogno di uno script che compilerà i web components nel file googlab.html; creiamo il file build.dart con questo contenuto:

import 'package:web_ui/component_build.dart';
import 'dart:io';

void main() {
  build(new Options().arguments, ['web/googlab.html']);
}

Per chiarire i concetti esposti nell’introduzione dell’articolo, sviluppiamo un’applicazione che mostra i valori di due variabili che cambiano nel tempo; il file web/googlab.html avrà questo contenuto:

<!DOCTYPE html>

<html>
<head>
  <meta charset="utf-8">
  <title>Googlab</title>
  <link rel="stylesheet" href="googlab.css">
</head>
<body>
  <h1>Googlab</h1>
  <p>{{ url }}</p>
  <p>Contatore: {{ conta }}</p>

  <hr/>

  <input type="text" bind-value="str">
  <div> Valore: {{str}}</div>
  <div> Lunghezza: {{str.length}}</div>

  <hr/>

  <input type="text" bind-value="str">

  <hr/>

  <button on-click="cambia()">Cambia URL</button>

  <script type="application/dart" src="googlab.dart"></script>
</body>

Il file googlab.dart invece sarà:

import 'dart:html';
import 'package:web_ui/watcher.dart' as watchers;

String str = '';
String url ="http://www.engeene.it";
int conta;

main() {
  conta = 0;
  window.setInterval(() {
    conta++;
    watchers.dispatch();
  }, 1000);
}

cambia(){
  url = url.toUpperCase();
}

Analizziamo questi due files: come si può vedere, non c’è nessuna funzione in googlab.dart che associ esplicitamente il valore di url alla pagina e per questo è necessario un compilatore, ovvero uno script che generi il documento finale; l’attributo bind-value consente la sincronizzazione fra la variabile in Dart e il valore corrente dell’elemento del DOM, ovvero al cambiamento della variabile in Dart cambia il valore dell’elemento del DOM e viceversa; in googlab.html due elementi input hanno l’attributo bind-value=”str”, quindi entrambi i campi saranno abbinati e sincronizzati con la variabile in Dart.

L’attributo on-click="cambia()" chiama la funzione cambia() che modifica la variabile url rendendola upper case; anche in questo caso nel codice non ci sono informazioni esplicite circa l’abbinamento del nuovo valore di url: grazie ai web components il valore corrente della variabile top-level url sarà sempre visibile; diversamente accade nel caso della variabile conta, che essendo manipolata dalla funzione window.setInterval() ha bisogno di essere esplicitamente resa visibile dall’interfaccia grafica, questo avviene tramite la funzione watchers.dispatch().

Ora che è tutto pronto non dobbiamo fare altro che “preparare” il documento finale, quindi eseguire build.dart. Possiamo scegliere di avviarlo sia dallo stesso DartEditor che da riga di comando digitando /percorso/a/googlab/build.dart. L’output di build.dart:

$ dart build.dart
Total time spent on web/googlab.html                         -- 206 ms

A questo punto il nostro compilatore build.dart genererà una nuova applicazione all’interno della directory web/out:

├── googlab.dart
├── googlab.html
├── googlab.html_bootstrap.dart
└── packages -> /home/utente/dart/googlab/packages

Per lanciare l’applicazione non dovremo far altro che eseguire web/out/googlab.html in Dartium dal menù Run->Run.

Nel corso di questa rubrica torneremo a parlare di web components, di MDV e della libreria web_ui, sottolineandone la modernità ed analizzandone tutti i vantaggi rispetto alla programmazione web tradizionale. Nel prossimo articolo introdurremo le funzioni server-side di Dart, vedremo come sviluppare un semplice server HTTP e come farlo comunicare con un client.

Leave a Reply

Claudio d'Angelis Articolo scritto da

Programmatore e studente di Informatica, appassionato di musica, web e sistemi UNIX. Collabora con Googlab dall'Ottobre 2012.

Contatta l'autore

Previous post:

Next post: