Il presente articolo è stato tradotto automaticamente.
Concetti sui dati
Accesso ai dati senza problemi proprio in JavaScript
Anche se penso di me stesso come un idraulico quando si tratta di sviluppo software, devo fare una discreta quantità di sviluppo client-side come bene. Anche in questa colonna, mi avventuro in applicazioni client, dove si intersecano con accesso ai dati. Ma quando il lato client è JavaScript, non è mai stato abbastanza — ogni curva di apprendimento è un mondo di dolore per me (e per il mio Twitter seguaci, che sono sottoposti a mio sfogo) e le mie abilità JavaScript, purtroppo, sono ancora carenti. Ma è sempre valsa la pena quando spingere attraverso il muro di mattoni e arrivare al successo. E tutto ciò che rende il lavoro in JavaScript più facile per me è qualcosa che accolgo a braccia aperte. Così, quando, durante una presentazione di gruppo utente Vermont.NET su applicazioni single-page, Ward Bell da IdeaBlade, ci ha dato un'occhiata a un'API di accesso ai dati di open source per JavaScript che lui e il suo team sono stati cooking up, ero molto interessato. Dal punto di vista della mia esperienza con Entity Framework, quello che ho visto era paragonabile all'utilizzo di EF per lo sviluppo Web client-side. L'API è chiamato brezza e al momento della stesura di questo articolo è in versione beta. Bell è stato generoso con il suo tempo per aiutarmi a saperne di più su Breeze per il bene di questa colonna. Si può ottenere presso breezejs.com, dove troverete anche una serie impressionante di documentazione, video e campioni.
La colonna di punti dati giugno 2012, "Dati associare OData in Web Apps con Knockout.js" (msdn.microsoft.com/magazine/jj133816), focalizzata sull'utilizzo di Knockout.js per eseguire più facilmente l'associazione dati sul lato client. Breeze funziona alla perfezione con Knockout, così ho intenzione di rivedere l'esempio dalla colonna di giugno. Il mio obiettivo è quello di vedere come l'introduzione di brezza potrebbe semplificare il mio sforzo codifica nel flusso di lavoro di esempio:
- Ottenere i dati dal server.
- Associazione e presentare i dati.
- Spingendo indietro le modifiche al server.
Sarò a piedi attraverso le parti critiche di una soluzione aggiornata, così si può vedere come i pezzi del puzzle si incastrano. Se si desidera seguire con una soluzione di set-up correttamente e prova le cose, è possibile scaricare la soluzione completa da archive.msdn.microsoft.com/mag201212DataPoints.
Il campione originale
Ecco i passaggi chiavi della mia precedente soluzione:
- Sul lato client, ho definito una classe person che Knockout può utilizzare per l'associazione dati:
function PersonViewModel(model) {
model = model || {};
var self = this;
self.FirstName = ko.observable(model.Name || ' ');
self.LastName = ko.observable(model.Name || ' ');
}
- I miei dati è stata fornita tramite un servizio dati OData, così accedere ai dati tramite datajs, un toolkit per consumare OData da JavaScript.
- Ho preso i risultati della query (che vengono restituiti come JSON) e creata un'istanza di PersonViewModel con i valori.
- Il mio app poi lasciare che il Knockout gestire l'associazione di dati, che coordina anche le modifiche apportate dall'utente.
- Ho preso l'istanza PersonViewModel modificato e aggiornato il mio oggetto JSON dai suoi valori.
- Infine, ho passato l'oggetto JSON per datajs per salvare di nuovo il server tramite OData.
Non mi preoccupai anche con dati correlati, come sarebbe aggiunto complessità molto di più per quel piccolo campione.
Un servizio aggiornato utilizzando ASP.NET Web API
Con Breeze, posso effettuare chiamate HTTP al mio servizio OData o di un servizio definito da ASP.NET Web API (asp. net/web-api). Ho acceso il mio servizio di ASP.NET Web API, che agisce contro lo stesso modello EF utilizzato precedentemente — con un'aggiunta. Il mio ex Campione esposto solo dati di persona. Ora ho correlati dati sotto forma di una classe di dispositivo, come ogni sviluppatore che so che ha una piccola collezione di dispositivi personali. Le funzioni rilevanti esposte dal mio ASP.NET Web API sono un GET, che restituisce i dati della persona; OTTENERE un'altra per i dati del dispositivo; e un POST unico per salvare le modifiche. Sto anche utilizzando una funzione di metadati per esporre lo schema dei miei dati, come mostrato Figura 1. Brezza utilizzerà questi metadati per capire il mio modello.
Figura 1 ingredienti chiave del mio servizio di Web API
readonly EFContextProvider<PersonModelContext> _contextProvider =
new EFContextProvider<PersonModelContext>();
[AcceptVerbs("GET")]
public IQueryable<Person> People()
{
return _contextProvider.Context.People;
}
[AcceptVerbs("GET")]
public IQueryable<Device> Devices()
{
return _contextProvider.Context.Devices;
}
[AcceptVerbs("POST")]
public SaveResult SaveChanges(JObject saveBundle)
{
return _contextProvider.SaveChanges(saveBundle);
}
[AcceptVerbs("GET")]
public string Metadata()
{
return _contextProvider.Metadata();
}
Breeze.NET sul Server
Prendere nota della variabile _contextProvider utilizzata in questi metodi. Non sto chiamando metodi del mio DbContext EF (PersonModelContext) direttamente. Invece, ho avvolto con la brezza EFContextProvider. Questo è il metodo di _contextProvider.Metadata provenienza, così come la firma di SaveChanges, che accetta un parametro saveBundle. Con saveBundle, Breeze sta per farmi inviare un insieme di modifiche dei dati dalla mia app, che passerà mio DbContext a persistere nel database.
Ho chiamato il mio app ASP.NET Web API "BreezyDevices", così ora posso richiesta dello schema utilizzando http://localhost:19428/api/breezydevices/metadata. E posso eseguire query per dati specificando uno dei metodi GET: http://localhost:19428/API/breezydevices/People.
Perché brezza sul lato client sarà una query e salvare un servizio remoto di ASP.NET Web API, posso rimuovere datajs dal mio client app.
Come brezza aiuterà il mio campione
Nell'ambito di questo esempio, si utilizzerà Breeze per concentrarsi su tre punti di dolore:
- Il mio servizio restituisce e accetta JSON nuda, ma ho bisogno di lavorare con oggetti JavaScript con proprietà osservabili Knockout per l'associazione dati dell'interfaccia utente.
- Voglio includere dati correlati, ma questo è difficile sul client.
- Ho bisogno di inviare più modifiche al server per il salvataggio.
Con Breeze, posso associare dati direttamente ai miei dati risultanti. Potrai configurare Breeze per utilizzare Knockout e, in risposta, creerà proprietà osservabili Knockout per me sotto le coperte. Questo significa che lavorare con dati correlati è molto più semplice perché non devo tradurre da JSON per oggetti associabili, e non devo fare lo sforzo supplementare di ridefinire grafici sul lato client utilizzando i miei risultati di query.
C'è qualche configurazione lato server coinvolti nell'utilizzo di Breeze. Ti lascio i dettagli che la documentazione di brezza, così posso mettere a fuoco sulla parte di accesso ai dati sul lato client del campione. E perché non c'è molto di più di brezza che cosa potrai essere sfruttando in questo esempio, una volta ho dato il sapore di essa ti consigliamo di visitare breezejs.com per saperne di più.
Figura 2 spettacoli dove brezza si inserisce nel flusso di lavoro sul lato server e lato client.
Figura 2 il Breeze.NET API aiuta sul Server mentre il BreezeJS API aiuta sul Client
Una query da brezza
La mia esperienza con OData e con Entity Framework rende l'esecuzione di query con brezza familiare. Io lavoro con la classe Breeze EntityManager. Il EntityManager è in grado di leggere il modello dei dati fornito dai metadati del servizio e produrre oggetti "entità" JavaScript sul proprio; non è necessario definire le classi di entità o scrivere mappatori.
C'è un po ' di configurazione lato client per fare così. Ad esempio, il seguente frammento di codice crea scorciatoie per alcuni spazi dei nomi di brezza e quindi configura Breeze per utilizzare API di Knockout e ASP.NET Web:
var core = breeze.core,
entityModel = breeze.entityModel;
core.config.setProperties({
trackingImplementation: entityModel.entityTracking_ko,
remoteAccessImplementation: entityModel.remoteAccess_webApi
});
È possibile configurare Breeze per utilizzare un numero di quadri di binding alternativi (come backbone o libreria Windows per JavaScript) e tecnologie di accesso ai dati (ad esempio OData).
Successivamente, creare un EntityManager che conosce l'uri relativo del mio servizio. Il EntityManager è paragonabile a un contesto di Entity Framework o OData. Esso agisce come il mio gateway alla brezza e memorizza nella cache i dati:
var manager = new entityModel.EntityManager('api/breezydevices');
Ora posso definire una query e avere il mio EntityManager eseguirlo per me. Questo codice non è troppo dissimile da utilizzando Entity Framework e LINQ alle entità, o di lavorare con qualsiasi client OData API, quindi è stata la mia parte preferita di imparare come usare Breeze:
function getAllPersons(peopleArray) {
var query = new entityModel.EntityQuery()
.from("People")
.orderBy("FirstName, LastName");
return manager
.executeQuery(query)
.then(function (data) {
processResults(data,peopleArray); })
.fail(queryFailed);
};
Sto facendo questo lato client e può eseguire la mia esecuzione di query in modo asincrono, motivo per cui il metodo executeQuery mi permette di definire che cosa fare quando la query viene eseguita con successo (allora) così come di cosa fare se non riesce (.fail).
Si noti che sto passando un array (che vedrà a breve è una matrice osservabile Knockout) a getAllPersons. Se l'esecuzione della query ha esito positivo, passare la matrice per il metodo processResults, che svuota l'array e poi compilarlo con i dati dal servizio. In precedenza sarebbe hai avuto scorrere i risultati e creare ogni istanza PersonViewModel me stesso. Usando Breeze, posso usare quello restituito dati direttamente:
function processResults(data, peopleArray) {
var persons = data.results;
peopleArray.removeAll();
persons.forEach(function (person) {
peopleArray.push(person);
});
}
Questo mi dà una matrice di oggetti person che presento nella visualizzazione.
La funzione getAllPersons è all'interno di un oggetto ho chiamato dataservice. Io uso dataservice nel prossimo bit di codice.
Un modello di visualizzazione Self-Populating
Il campione di mio articolo June Knockout, le query e i risultati erano separati dalla classe PersonViewModel che ho usato per l'associazione dati nella visualizzazione. Così ho eseguito la query e tradotto i risultati in un'istanza di PersonViewModel con il codice di mappatura che ho scritto. Come non bisogno di mapping codice o un PersonViewModel con Breeze, io il mio app un po ' più intelligente questo tempo e farlo visualizzare una matrice di oggetti Person recuperati dal database di mio dataservice. Per riflettere questo, ora ho un oggetto denominato PeopleViewModel. Questo espone una proprietà di persone che ho definito come una matrice osservabile ad eliminazione diretta che io popolo utilizzando dataservice.getAllPersons:
(function (root) {
var app = root.app;
var dataservice = app.dataservice;
var vm = {
people: ko.observableArray([]),
}
};
dataservice.getAllPersons(vm.people);
app.peopleViewModel = vm;
}(window));
Nell'esempio di download troverete un file chiamato main.js, che è il punto di partenza per la logica dell'applicazione. Esso contiene la seguente riga di codice che chiama il metodo applyBindings Knockout:
ko.applyBindings(app.peopleViewModel, $("content").get(0));
Il metodo applyBindings si connette i metodi e le proprietà di visualizzazione modello per i controlli di interfaccia utente HTML tramite le associazioni dati dichiarati nella visualizzazione.
In questo caso, la vista è un piccolo pezzo di HTML nel mio index.cshtml. Si noti il markup di associare ad eliminazione diretta che si lega e viene visualizzato il nome e cognome di ogni oggetto persona nella matrice di persone:
<ul data-bind="foreach: people">
<li class="person" >
<label data-bind="text: FirstName"></label>
<label data-bind="text: LastName"></label>
</li>
</ul>
Quando eseguo il mio app ottenere una visualizzazione di sola lettura dei miei dati di persona, come mostrato Figura 3.
Figura 3 utilizzando Breeze e Knockout di utilizzare facilmente i dati in JavaScript
Tweaking JavaScript e Knockout per consentire la modifica
Come ricorderete dalla colonna di giugno, Knockout rende facile associare i dati per la modifica. Insieme al vento, questa è una grande combinazione per modifica dati e la persistenza si torna al server.
Aggiungere innanzitutto una funzione all'oggetto dataservice che chiama il metodo manager.saveChanges Breeze. Quando viene chiamato, la brezza EntityManager fasci le modifiche in sospeso e li posti al servizio Web API:
function saveChanges() {
manager.saveChanges();
}
Allora ti espongo la nuova funzione saveChanges come una caratteristica del dataservice:
var dataservice = {
getAllPersons: getAllPersons,
saveChanges: saveChanges,
};
Ora il mio PeopleViewModel oggetto deve esporre il proprio metodo per l'associazione save alla vista; il modello di visualizzazione salvare i delegati di funzione per il metodo saveChanges dataservice. Qui uso un JavaScript "la funzione anonima" per definire il modello di visualizzazione Salva:
var vm = {
people: ko.observableArray([]),
save: function () {
dataservice.saveChanges();
},
};
Successivamente, sostituire le mie etichette con gli elementi di input (caselle di testo) così l'utente può modificare gli oggetti persona. Devo passare da "testo" la parola chiave "valore" di Knockout per attivare l'associazione bidirezionale all'input dell'utente. Aggiungere anche un'immagine con un evento click associato al metodo del PeopleViewModel.save:
<img src="../../Images/save.png"
data-bind="click: save" title="Save Changes" />
<ul data-bind="foreach: people">
<li class="person" >
<form>
<label>First: </label><input
data-bind="value: FirstName" />
<label>Last: </label> <input
data-bind="value: LastName" />
</form>
</li>
</ul>
Niente altro. Brezza e Knockout si prenderà cura di tutto il resto! Potete vedere i dati visualizzati per l'editing in Figura 4.
Figura 4 utilizzando Breeze per salvare i dati tramite JavaScript
Posso modificare uno qualsiasi o tutti questi campi e fare clic su Salva pulsante. La brezza EntityManager sarà raccogliere tutte le modifiche dei dati e li spingono fino a server, che a sua volta li invia a Entity Framework per aggiornare il database. Mentre non estendere questa demo per includere inserimenti ed eliminazioni, Breeze può certamente gestire quelle modifiche pure.
E per il grande finale — aggiunta nei dati relativi
Questa è la parte di qualsiasi applicazione JavaScript che molti sviluppatori dread — e questo è esattamente il motivo che ho voluto scrivere questo articolo.
Io fare una piccola modifica al mio script e aggiungere un po ' markup al form che trasformerà ogni persona in un master modificabile /persona di dettaglio.
Il cambiamento nel mio script sarà in dataservice, dove potrai modificare la query aggiungendo nella brezza espandere metodo query a desideroso -caricare dispositivi di ogni persona, insieme con la persona. Espandere è un termine che potrebbe riconoscere da OData o NHibernate ed è simile alla inclusione in Entity Framework (Breeze ha anche il supporto per caricare facilmente i dati correlati dopo il fatto):
var query = new entityModel.EntityQuery()
.from("People")
.expand("Devices")
.orderBy("FirstName, LastName");
Sarà poi modificare la mia vista che sa come visualizzare i dati del dispositivo, come mostrato Figura 5.
Figura 5 modifica la vista per visualizzare i dati del dispositivo
<ul data-bind="foreach: people">
<li class="person" >
<form>
<label>First: </label><input
data-bind="value: FirstName" />
<label>Last: </label> <input
data-bind="value: LastName" />
<br/>
<label>Devices: </label>
<ul class="device" data-bind="foreach: Devices">
<li>
<input data-bind="value: DeviceName"/>
</li>
</ul>
</form>
</li>
</ul>
Questo è quanto. Come si può vedere Figura 6, brezza gestisce il desideroso di caricamento e la costruzione dei grafici sul lato client. Coordina inoltre i dati da inviare al servizio per gli aggiornamenti. Sul lato server, la brezza EFContextProvider ordina fuori tutti i dati di modifica che riceve e fa in modo che Entity Framework ottiene che cosa ha bisogno rendere persistenti i dati nel database.
Figura 6 che consumano e salvataggio dati correlati
Mentre questo era semplice con una relazione uno-a-molti, al momento della stesura di questo articolo la versione beta di brezza non supporta relazioni molti-a-molti.
Accesso ai dati lato Client senza dolore
Bell mi dice che era la propria dolorosa esperienza di lavorare su un progetto che è stato sia JavaScript-intensivo e dati-accesso-intensivo che ha ispirato la brezza. La sua azienda, IdeaBlade, ha da sempre puntato sulla creazione di soluzioni per risolvere i problemi di gestione di dati disconnessi, e gli sviluppatori sono stati in grado di portare una grande quantità di esperienza a questo progetto open source. Sono sempre stato restio ad imbarcarsi in progetti che utilizzano un sacco di JavaScript, perché le mie capacità sono zoppo per cominciare, e so che i bit di dati-accesso mi renderebbe infelice. Ero molto interessato nella brezza, non appena l'ho visto. E anche se io ho solo graffiato la superficie, l'ultimo bit di quello che ti ho mostrato in questo articolo — quanto fosse facile da consumare e salvare dati correlati — è quello che davvero mi ha conquistato.
Julie Lerman è un Microsoft MVP, mentore e consulente .NET che risiede nel Vermont. È possibile trovare le sue presentazioni relative all'accesso ai dati e altri argomenti su Microsoft .NET in occasioni di conferenze che si tengono in tutto il mondo. Blog di lei a /Blog ed è l'autore di "Programming Entity Framework" (2010) così come un codice prima edizione (2011) e un DbContext (2012), tutti da o ' Reilly Media. È possibile seguirla su Twitter all'indirizzo twitter.com/julielerman.
Grazie all'esperto tecnica seguente per la revisione di questo articolo: Ward Bell