Visualizzazione post con etichetta coffeescript. Mostra tutti i post
Visualizzazione post con etichetta coffeescript. Mostra tutti i post

venerdì 13 luglio 2012

Ajax + Prototype + CoffeeScript

In rete abbondano gli esempi CoffeeScript per chiamate Ajax con la libreria jQuery. Se uno - come me - preferisce Prototype, è abbandonato al proprio destino.

Perciò pubblico qui sotto l'esempio di una pagina CoffeeScript con chiamate Ajax in Prototype.

//= require prototype

pe = null

invitations_args =
  method: 'get'
  onSuccess: (transport) ->
    inviter = transport.responseText
    if inviter.length > 1
      $('invitation').show()
      $('proposal').update
             (inviter + ' invites you to join a game:')
      pe.stop()
      return
  onFailure: ->
    $('invitation').show() 
    $('proposal').update('Error retrieving invitation')
    return

invitations = ->
  new Ajax.Request 
      '/player/lookforinvitations', invitations_args
  
main_loop = ->
  pe = new PeriodicalExecuter( invitations, 3 )

Event.observe(window, 'load', main_loop)


La parte principale (main_loop) è invocata sull' onLoad della pagina HTML. Qui, un PeriodicalExecuter esegue una chiamata Ajax ogni tre secondi ad un metodo (/player/lookforinvitations) che cerca se sul database qualcuno ci ha invitato a giocare. Se sì la pagina mostra un messaggio: ad esempio: Pippo ti invita a giocare con lui, e ferma il processo PeriodicalExecuter. Altrimenti la pagina continua ad inviare richieste Ajax al server finchè l'utente non cambia pagina.

(Una cosa interessante e che mi ha fatto perdere molto tempo è che anche in CoffeeScript l'ordine in cui vengono definite le funzioni è importante!! Se mettete ad esempio Event.Observe all'inizio del file, otterrete un errore di oggetto undefined: l'oggetto in questione è main_loop, che viene definito solamente più sotto!)




mercoledì 11 luglio 2012

CoffeeScript e le var locali


CoffeeScript è un linguaggio moderno, sintetico ed efficace che compila in JavaScript. Nei progetti web complessi, l'uso di CoffeeScript si sta via via imponendo, perché rende la creazione e la manutenzione del codice lato client molto più veloce e snella.

Una delle prime difficoltà, tuttavia, che si incontrano quando si comincia ad usare CoffeeScript è il fatto che per convenzione tutte le variabili (e quindi anche le funzioni, che in CoffeeScript sono anonime e associate ad un nome di variabile) sono locali.

Un esempio può chiarire meglio. Supponiamo di avere questa semplice pagina in HTML5:

<!DOCTYPE html>
<html>
<head>
    <title>CoffeeScript Palestra</title>
    <link rel="stylesheet" href="css/main.css">
    <script src="js/vendor/jquery-1.7.2.min.js"></script>
    <script src="js/script.js"></script>
</head>
<body>
    <h2>CoffeeScript Scripts</h2>
    <p>Premi <a href="#" onclick="run()">qui</a></p>
    <div id="pippo">&nbsp;</div>
</body>
</html>

Se l'utente preme il link "qui" vogliamo che accada qualcosa, ad esempio compaia la scritta "Ciao Mondo!"

La prima idea che ci viene in mente è quella di scrivere due funzioni, una che ritorna "Ciao Mondo" e una che aggiorna il contenuto del DIV "Pippo" appunto con "Ciao Mondo", in questo modo:

# COFFEESCRIPT SCRIPTS

run = ->
  $("#pippo").html(helloworld)
  null


helloworld = -> 'Ciao Mondo!'

Mettiamo questo codice nel file "script.coffee" e poi lo compiliamo con CoffeeScript. Otterremo script.js che viene poi richiamato dal nostro file HTML (sotto la riga che carica JQuery).

Peccato che una volta eseguito il tutto, quando l'utente preme "qui", non accade nulla.

Il motivo è che il compilatore CoffeeScript traduce le due funzioni "run" e "helloworld" come funzioni locali, quindi di fatto invisibili all'esterno dello stesso codice. Ecco il codice compilato:

// Generated by CoffeeScript 1.3.3
(function() {
  var run, helloworld;

  run = function() {
    $("#pippo").html(helloworld);
    return null;
  };

  helloworld = function() {
    return 'Ciao Mondo!';
  };

}).call(this);

E' giusto che sia così: infatti per evitare conflitti di nomi e variabili globali che rimangono inutilmente appese, mentre in JavaScript è buona norma dichiarare tutto con "var", in CoffeeScript questa diviene la regola.

Per "esportare" il nome di una variabile all'esterno si può agire in diversi modi. Quello che personalmente preferisco è di associare allo spazio dei nomi dello script un nome che espliciti la sua funzione di "esportatore" (ad esempio: exports), e poi di dichiarare le variabili da esportare come appartenenti a questo spazio.

# COFFEESCRIPT SCRIPTS

exports = this

exports.run = ->
  $("#pippo").html(helloworld)
  null


helloworld = -> 'Ciao Mondo!'

In questo modo, la funzione run() - o meglio, la variabile 'run' associata alla funzione anonima - diventa visibile all'interno del nostro file HTML e perciò direttamente utilizzabile.


// Generated by CoffeeScript 1.3.3
(function() {
  var exports, helloworld;

  exports = this;

  exports.run = function() {
    $("#pippo").html(helloworld);
    return null;
  };

  helloworld = function() {
    return 'Ciao Mondo!';
  };

}).call(this);


Come conseguenza non banale, le funzioni ancillari come per esempio la 'helloworld', non vengono esposte, diventando di fatto 'private'.