E' da un po' che mi diverto con JavaScript. Non gli avevo mai dato peso, anzi, a dir la verità ho pensato spesso che fosse un linguaggio da pazzi schizzati con la totale assenza di regole (ed io, che sono nato negli stessi anni di C#, alle regole ci sono affezionato).
Perché JavaScript? Perché ormai le applicazioni web non possono esistere senza. Senza l'appeal che è in grado di dare anche solo una piccola animazione o la totale assenza di postback.
Quando infatti ci si approccia ad una nuova applicazione web di questi tempi, è impossibile ormai non prescindere da:

  • uno sviluppo di back-end: a cui ormai siamo abituati, anche su SharePoint con il suo modello a oggetti,
  • uno sviluppo di front-end: ed è qui la novità.

Dicesi sviluppo di front-end tutta l'architettura client-side della nostra applicazione web (JavaScript) assieme all'implementazione della struttura della pagina (HTML5) e del suo aspetto grafico (CSS3).
Ecco quindi che uno sviluppatore SharePoint con me, abituato ad utilizzare il postback, i web control e, per il suo periodo di massimo splendore Silverlight, si ritrova ad imparare tutto un nuovo mondo di tecnologie a cui fino ad ora era rimasto allo scuro.
Oltretutto, con l'arrivo di SharePoint 2013, JavaScript è diventata una vera e propria CORE SKILL per uno sviluppatore SharePoint, mentre invece in tutti questi anni siamo diventati dei super eroi del server object model.
Quello che mi serviva era capire bene erano le basi di questo linguaggio e i principali pattern di sviluppo che mi avrebbero permesso di scrivere applicazioni di front-end robuste, in linea con gli standard del momento e con un'alta user experience.
Okkei, la prima cosa che ho imparato quindi è che JavaScript è un linguaggio dinamico, che non ha un compilatore (ma usa il browser per beccare solo gli errori a run-time), con solamente 7 tipi primitivi, case sensitive, basato sul concetto di funzioni, che (e qui è stata una grande sorpresa) è orientato agli oggetti e che, soprattutto, JAVASCRIPT NON E’ C#.
Non è C# perché permette delle cose scellerate tipo:

function foo() {

for(var i = 0; i < 10; i++) {
//do anything you want }
alert(i); //will display 10 }

...tipo:

function foo() {

for(var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
foo('here', 'you','can','pass','what','ever','you','want');

...e tipo:

function checkEquals(a, b) {

return a == b;
}
function multiplication(a, b) {
return a * b;
}
var result = checkEquals('', 0); //returns true var result2 = checkEquals('0', 0); //returns true var result3 = multiplication('4', 4); //returns 16

Cose che per noi sviluppatori C# sono da pazzi.
Al che ho cercato di prendermi un po' di capisaldi ed è venuto fuori che:
  • le variabili si istanziano utilizzando la parola chiave "var" e che, in base al valore attribuito, cambiano il loro tipo (anche a run-time)
  • l'esecuzione del codice va dall'alto al basso della pagina
  • esistono gli oggetti e che possono essere creati in differenti maniere:
    • sfruttando la classe Object
    • sfruttando la sintassi JSON (detta anche "literal notation")
    • sfruttando le funzioni
  • esistono anche le proprietà e i metodi
  • esistono i namespace e il namespace di root "window"
  • esistono i concetti di scoping delle variabili ed ereditarietà (che sono molto diversi da quelli di C#)
  • l'ugualianza (o la disugualianza) si usa tramite l'uso di 3 uguali, perchè con 2 uguali viene fatto un cast e poi il controllo del valore
  • una funzione JavaScript in realtà è un oggetto
  • una funzione JavaScript può essere assegnata ad una variabile, ad un oggetto, ad una proprietà o può essere passata come parametro
  • una funzione JavaScript ha la parola chiave "this" (che ha però un valore diverso da quello che ha in C#)
  • esiste l'oggetto "prototype", che viene creato in automatico ogni volta che si crea una nuova istanza di un oggetto e che è veramente utile per risparmiare memoria
  • esiste il concetto di closure, che da una "durata di vita" alle variabili diversa da quella delle variabili C#
  • se inserisco la stringa 'use strict' come prima riga del mio script mi assicuro di scrivere codice pulito ed evitare sfondoni come dimenticarmi l'utilizzo della parola chiave "var" per la definizione di una variabile (così è il browser che me lo indica a run-time)

Queste nozioni mi sono diventate veramente utili quando poi mi sono messo a studiare un po’ di pattern. Ho letto più volte con piacere questo:
http://addyosmani.com/resources/essentialjsdesignpatterns/book/

E' veramente una bella risorsa, ve la consiglio.
Da lì ho capito che potevo scrivere del codice JavaScript che assomigliasse un po' di più al codice C# cui sono stato abituato fino a poco tempo fa e la cosa mi piaceva molto.

//namespaces

window.D4S = window.D4S || {};

window.D4S.SP13 = window.D4S.SP13 || {};

//constructor pattern D4S.SP13.Contact = function(firstName, lastName, mail, id) {
var self = this;

self.FirstName = firstName;
self.Title = lastName;
self.Id = id;
self.EMail = mail;
self.__metadata = { 'type': 'SP.Data.RubricaListItem' };
self.ShowFullName = function() {
alert(self.FirstName + ' ' + self.Title);
};
}
//instances var peppe = new D4S.SP13.Contact('Peppe', 'Marchi', 'giuseppe.marchi@dev4side.com');
var miro = new D4S.SP13.Contact('Miro', 'Radenovic', 'miro.radenovic@dev4side.com');
peppe.ShowFullName(); //Peppe Marchi miro.ShowFullName(); //Miro Radenovic

Ho capito anche che, se volevo fare le cose per bene e controllare la memoria che la mia applicazione di front-end occupava all'interno del browser, dovevo farmi amico l’oggetto "prototype" e sfruttarlo nel migliore dei modi.

window.D4S = window.D4S || {};

window.D4S.SP13 = window.D4S.SP13 || {};

D4S.SP13.Contact = function (id, firstname, lastname, email) {
var self = this;
self.Id = id;
self.FirstName = firstname;
self.Title = lastname;
self.EMail = email;
};
D4S.SP13.Contact.prototype.ShowFullName = function () {
return this.FirstName + ' ' + this.Title;
};
var peppe = new D4S.SP13.Contact(1, 'Peppe', 'Marchi', 'giuseppe.marchi@dev4side.com');
var miro = new D4S.SP13.Contact(2, 'Miro', 'Radenovic', 'miro.radenovic@dev4side.com');

alert(peppe.ShowFullName());
alert(miro.ShowFullName());

Fin quando poi ho parlato con Roberto che mi ha introdotto KnockoutJs, libreria open-source con qualche anno di esperienza ormai che mi permette di implementare un pattern che conosco molto bene dalle mie esperienze di lavoro con Silverlight: il pattern MVVM (Model-View-ViewModel).
Fantastico!
Con questa libreria e veramente poche righe di codice, si fanno delle cose pazzesche. Questo perché KnockoutJs ti permette di fare un binding dichiarativo sulla pagina, staccando totalmente quella che è l'interfaccia dell'applicazione dalla logica di business ed occupandosi di fare refresh della UI a fronte di un cambiamento di una proprietà del ViewModel (proprietà definita "osservabile"), di utilizzare dei template di rendering HTML e di fare dependency tracking.
Oltre al sito ufficiale della libreria, vermante ben fatto, vi lascio qualche lettura molto interessante:


Abbiamo visto già un po' di sintassi di KnockoutJs nei precedenti post e seguirà una serie di post utili a farvi capire come sfruttare questa libreria all'interno di applicazioni SharePoint 2013 (Apps o Farm solutions che siano).
In generale, è importante ricordarsi che se volete che l'interfaccia venga modificata in automatico al cambiamento del valore di una proprietà del ViewModel da KnockoutJs è necessario che tale proprietà venga dichiarata come "osservabile" (ko.observable() o ko.observableArray()) e che, una volta che una proprietà è stata segnata come osservabile, va seguita questa sintassi:
  • per la lettura: var valore = model.property()
  • per la scrittura: model.property(‘nuovo valore’);


Vi assicuro che vi ci abituerete presto.
Vi assicuro anche che, se non conoscete per niente o poco JavaScript, vi ci potete divertire tanto e oltretutto acquisite un bagaglio tecnico veramente molto utile di questi tempi.