RIAServices.jQuery e la Gestione Dati via Javascript
Cristian Merighi ()

RIA/JS per applicazioni business che sfruttano il pattern MVVM utilizzando solo markup e codice javascript.
Questo articolo è da considerarsi obsoleto. Alcune funzionalità potrebbero non essere più disponibili e non è possibile aggiungere commenti.
RIAServices.jQuery (aka RIA/JS) è un progetto firmato Microsoft che - nel marasma attuale dei framework MVVM client - promette di essere una soluzione affidabile nel prossimo futuro e quindi degna di tempo speso per impararne l'utilizzo (ecco me la sono gufata...).
Il sito di riferimento è al solito codeplex, dove il progetto è definito "In progress" e dove effettivamente
continuano ad essere pubblicate rincuoranti updates (ultimo quello di agosto 2011).
Come utilizzare le librerie che tutte assieme compongono RIA/JS?
A dire il vero esiste già un progetto (BigShelf project) che prevede d'illustrarne le modalità d'impiego, ma:
- Sono dolori di panza a cercare di farlo girare. Io non ci sono riuscito;
- È necessario installare librerie di terze-parti che nulla hanno a che fare con RIA/JS in sé (pessima clausola questa).
Vediamo allora di istruire passo-passo sulla configurazione di una WebApplication (se il site è lo stesso che contiene i RIAServices è necessario utilizzare questo tipo di progetto web, e non il WebSite, in Visual Studio 2010)
per l'utilizzo di RIA/JS.
Attraverso il potentissimo distributore di packages NuGet
(per i pochi che ancora non l'avessero installato → nuget.org/)
vediamo di andare ad incorporare le librerie (client e server) necessarie:
Il pacchetto è cercabile online con la query di ricerca «RIAServices.jQuery».
Successivamente all'installazione del pacchetto, vedrete nuovi elementi inseriti nel progetto:
 |
Il pacchetto include (come evidenziato nella prima immagine) la libreria jQuery 1.5.2
(al momento in cui scrivo quest'articolo la versione ultima è la 1.6.2 e funziona anch'essa perfettamente).
Oltre ad essa, e sempre strettamente correlate al mondo jQuery che definirei "usuale" in termini di UI, i plugin
jQuery.Templates ($.tmpl) e jQuery.Validation ($.validation) quest'ultimo strettamente correlato ai metadati
gestiti dal framework (cfr. Ln 162 @ RemoteDataSource.js).
Una libreria non inclusa automaticamente ma di cui caldeggio l'utilizzo è quella jQuery.DataLink (api.jquery.com/link),
ne vedremo l'utilizzo all'interno del codice d'esempio che seguirà. Una mia speranza è altresì vederla fusa assieme a jquery.observable in una unica.
Si noti l'inclusione - evidenziata sopra - della libreria server Microsoft.ServiceModel.DomainServices.Hosting.dll.
Assieme ad essa è stato modificato il contenuto del file di configurazione Web.Config (vedi codice sotto).
|
Ecco di seguito un blocco di codice incluso nel Web.config con l'installazione del pacchetto. Abilita un EndPoint Json per il RIAService per il quale è prevista la trasmissione dei metadati relativi alle entities:
Web.config:
- <system.serviceModel>
- <domainServices>
- <endpoints>
- <add name="soap" type="Microsoft.ServiceModel.DomainServices.Hosting.SoapXmlEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
- <add name="JSON" type="Microsoft.ServiceModel.DomainServices.Hosting.JsonEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" transmitMetadata="true" />
- </endpoints>
- </domainServices>
- <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
- </system.serviceModel>
Ora poniamo di aver già configurato il nostro model utilizzando - ad esempio - Entity Framework (salto questo aspetto che considero noto a chi legge) e di avere al suo interno una semplicissima classe
Family costituita da due membri: un ID (Guid) e un Name (String). La arricchisco dei metadati cui abbiamo accennato sopra:
Family partial class:
- [MetadataType(typeof(FamilyMetadata))]
- public partial class Family
- {
- public Family()
- {
- this._ID = Guid.NewGuid();
- }
- }
-
- [DisplayColumn("Name")]
- sealed class FamilyMetadata
- {
- [Key]
- public Guid ID { get; set; }
-
- [Required, StringLength(63)]
- public string Name { get; set; }
- }
Focalizzando l'attenzione sulla property Name vediamo come essa venga flaggata Required e con massima lunghezza ammissibile a 63 caratteri.
Ora passiamo alla creazione del nostro RIAService: aggiungi nuovo elemento...
L'url del nostro servizio avrà la seguente forma pubblica: http://mysite/Namespace-SubNamespace-ClassName.svc (i punti presenti tra i vari namespaces vanno sostituiti con trattini).
All'interno del codice generato vedrete metodi creati per il recupero e la scrittura dei dati che ommettiamo di riportare qui.
Saltiamo ora diretti al nocciolo del problema: l'utilizzo delle librerie javascript!
Ora che tutto è debitamente configurato non ci resta che scrivere la pagina per il consumo dei dati. Eccone l'intero contenuto:
Html:
- <script src="Scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
- <script src="Scripts/jquery.tmpl.min.js" type="text/javascript"></script>
- <script src="Scripts/jquery.datalink.js" type="text/javascript"></script>
- <script src="Scripts/jquery.validate.min.js" type="text/javascript"></script>
- <script src="Scripts/jquery.observable.js" type="text/javascript"></script>
- <script src="Scripts/jquery.datasource.js" type="text/javascript"></script>
- <script src="Scripts/DomainServiceProxy.js" type="text/javascript"></script>
- <script src="Scripts/EntitySet.js" type="text/javascript"></script>
- <script src="Scripts/DataContext.js" type="text/javascript"></script>
- <script src="Scripts/DataSource.js" type="text/javascript"></script>
- <script src="Scripts/LocalDataSource.js" type="text/javascript"></script>
- <script src="Scripts/RemoteDataSource.js" type="text/javascript"></script>
- <script src="Scripts/AssociatedEntitiesDataSource.js" type="text/javascript"></script>
-
- <script type="text/javascript">
- $(function () {
- var svcUri = 'http://gauss/pacem_housesystem/Services/Pacem-HouseSystem-Services-HouseSystemRIAService.svc';
- var render = function (families) {
- var family = families[0];
- $("form input[name='Name']").val(family.Name);
- // track changes at UI level
- $("form").link(family)
- // get validation policies and revert 'em into the layout
- .validate({ rules: ds.getEntityValidationRules().rules });
- //
- $(family).bind("changeField", function (args, field, value) {
- if (field === "Name") {
- $("#familyName").html(value);
- }
- // IMPORTANT: track changes at datasource level!
- $.observable(family).setProperty(field, value);
- });
- //
- $.each(family, function (fieldName, value) {
- $(family).setField(fieldName, value);
- });
- // handlers on both submit and cancel buttons
- $('#submit').click(function (evt) {
- evt.stopPropagation();
- evt.preventDefault();
- if ($('form').valid()) {
- ds.commitChanges();
- }
- else
- alert('not valid!');
- });
- $('#cancel').click(function (evt) {
- evt.stopPropagation();
- evt.preventDefault();
- ds.dataContext().revertChanges(family, 'Name');
- // update layout via datalink (tedious)
- $(family).setField('Name', family.Name);
- });
- // just a test method
- ds.option("entityStateChange", function () {
- //alert('entity state changed');
- $('#changeTracker b').html("yes");
- });
- };
- var ds = $.dataSource({ serviceUrl: svcUri,
- queryName: "GetFamilySet",// ← default retrieving method generated by the RIAService designer
- bufferChanges: true,// buffer all occurred changes, then commit
- refresh: render
- }).refresh();
- });
-
- </script>
-
- <input type="text" name="Name" />
-
- <div id="familyName">...</div>
-
- <div id="changeTracker">has changes: <b></b></div>
-
- <input id="submit" type="submit" value="submit" />
- <input id="cancel" type="reset" value="cancel" />
Porzione di screenshot:
Fiddler:
Spero possa essere stato d'aiuto.
Take care. Bye.