Settembre 2015

Volume 30 Numero 9

Il presente articolo è stato tradotto automaticamente.

Punti dati - Considerazioni sul data binding di JavaScript: ora con Aurelia

Da Julie Lerman

Julie LermanNon sono mai stato gran parte di uno sviluppatore front-end, ma ogni tanto in tanto il motivo per giocare con un'interfaccia utente. Nel mio articolo di giugno 2012, dopo la visualizzazione di una presentazione di gruppo utente su Knockout, fatto delle ricerche e ha scritto un articolo sull'associazione dati OData in un sito Web mediante Knockout (msdn.microsoft.com/magazine/jj133816). Dopo alcuni mesi, ho scritto sull'aggiunta di Breeze.js in combinazione per semplificare ulteriormente l'associazione dati con Knockout (msdn.microsoft.com/magazine/jj863129). Quando ho parlato modernizzazione una vecchia applicazione Web Form di ASP.NET 2.0 e utilizzando nuovamente Knockout nel 2014, noterai teased da alcuni elementi Friend che ha detto che Knockout è "così 2012". Framework più recenti quali angolare ha anche l'associazione dati e molto altro ancora. Ma non ero interessano realmente il "molto di più," in modo Knockout è stato corretto automaticamente.

Bene, ora 's 2015 e mentre Knockout è ancora valido e pertinenti e awesome per l'associazione dati JavaScript, desidera dedicare del tempo con una delle nuove strutture e scelto Aurelia (Aurelia.io) poiché SO tanti di quegli sviluppatori Web che sono entusiasti è. Aurelia è stato avviato da Rob Eisenberg, che è stato protetto da Durandal, un altro framework di client JavaScript, se ha arrestato produzione su di esso per andare a lavoro del team angolare di Google. Alla fine ha lasciato angolare e, invece di riattivazione Durandal, creato da zero Aurelia backup. Esistono una vasta gamma di caratteristiche interessanti Aurelia. Molto più sapere con certezza, ma desidera condividere con alcuni trucchi di associazione dati, nonché un po' di programmi con EcmaScript 6 (ES6), la versione più recente di JavaScript, è diventato uno standard in giugno 2015 ho appreso.

Un'API di fornire i dati al sito Web di ASP.NET Web

Si sta utilizzando un'API Web ASP.NET è stato creato per esporre i dati che sono persistenza con Entity Framework 6. L'API Web include una vasta gamma di metodi semplici per essere chiamato tramite HTTP.

Il metodo Get, illustrato nella Figura 1, accetta in Progettazione query e alcuni parametri di spostamento e li passa al metodo repository che recupera un elenco di oggetti esperto e i relativi oggetti Clan utilizzando un DbContext di Entity Framework. Una volta il metodo Get presenta i risultati a disposizione, trasforma i risultati in un set di ViewListNinja trasferire oggetti DTO (Data), definiti altrove. Questo è un passaggio importante il modo in cui che viene serializzato JSON, ovvero un po' eccessivamente zelanti con riferimenti circolari il Clan verso altri Ninjas. Con DTO, evitare di una quantità sarebbe uno spreco di dati trasmessi in rete, viene generata di elaborare i risultati per adattarli novità sul client.

Figura 1 il metodo Get dal Web API

public IEnumerable<ViewListNinja> Get(string query = "",
  int page = 0, int pageSize = 20)
  {
    var ninjas = _repo.GetQueryableNinjasWithClan(query, page, pageSize);
    return ninjas.Select(n => new ViewListNinja
                              {
                                ClanName = n.Clan.ClanName,
                                DateOfBirth = n.DateOfBirth,
                                Id = n.Id,
                                Name = n.Name,
                                ServedInOniwaban = n.ServedInOniwaban
                              });
    }

Figura 2 viene illustrata una visualizzazione di JSON risultante da tale metodo in base a una query per recuperare due oggetti esperto.

Risultati JSON dalla richiesta di API Web per l'elenco di Ninjas
Figura 2 risultati JSON dalla richiesta di API Web per l'elenco di Ninjas

L'esecuzione di query Web API tramite il Framework Aurelia

Aurelia paradigma coppie un modello di visualizzazione (una classe JavaScript) con una visualizzazione (un file HTML) ed esegue tale associazione tra i due. Pertanto, ho un file ninjas.js e un file ninjas.html. Il modello di visualizzazione Ninjas è definito come dotato di una matrice di Ninjas, nonché un oggetto esperto:

export class Ninja {
  searchEntry = '';
  ninjas = [];
  ninjaId = '';
  ninja = '';
  currentPage = 1;
  textShowAll = 'Show All';
  constructor(http) {
    this.http = http;
  }

Il metodo più importante di ninjas.js è retrieveNinjas, che chiama l'API Web:

retrieveNinjas() {
  return this.http.createRequest(
    "/ninjas/?page=" + this.currentPage +
    "&pageSize=100&query=" + this.searchEntry)
    .asGet().send().then(response => {
      this.ninjas = response.content;
    });
  }

Altrove nel Web ho impostato l'URL di base che Aurelia app verrà trovare e incorporarlo nell'URL della richiesta:

x.withBaseUrl('http://localhost:46534/api');

Vale la pena notare che il file ninjas.js è semplicemente JavaScript. Se è stato utilizzato Knockout, si ricorderà che è necessario impostare il modello di visualizzazione utilizzando la notazione di ritaglio in modo che quando l'oggetto è associato al markup, Knockout saprà cosa fare con esso. Non è nel caso di Aurelia.

La risposta include ora l'elenco dei Ninjas e che è impostata sulla matrice ninjas del mio modello di visualizzazione ottiene torna alla pagina ninjas.html che ha attivato la richiesta. Non c'è niente nel markup che identifica il modello, che ha preso in considerazione in quanto il modello è associato a HTML. Infatti, la maggior parte della pagina è standard HTML e JavaScript, con pochi comandi speciali che Aurelia trovare e gestire.

Associazione dati, stringa interpolazione e formattazione

La parte più interessante di ninjas.html è il tag div, viene utilizzato per visualizzare l'elenco di ninjas:

<div class="row">
  <div  repeat.for="ninja of ninjas">
    <a href="#/ninjas/${ninja.Id}" class="btn btn-default btn-sm" >
      <span class="glyphicon glyphicon-pencil" />  </a>
    <a click.delegate="$parent.deleteView(ninja)" class="btn btn-default btn-sm">
      <span class="glyphicon glyphicon-trash" />  </a>
    ${ninja.Name}  ${ninja.ServedInOniwaban ? '[Oniwaban]':''}
    Birthdate:${ninja.DateOfBirth | dateFormat}
  </div>
</div>

Il primo markup Aurelia specifico in tale codice è repeat.for "esperto di ninjas," che segue un paradigma ES6 del ciclo. Poiché Aurelia comprehends il modello di visualizzazione, consapevole del fatto che "ninjas" la proprietà definita come una matrice. La variabile "esperto" può essere qualsiasi nome, ad esempio "foo". Rappresenta semplicemente ogni elemento della matrice ninjas. Ora è sufficiente scorrere gli elementi nella matrice ninjas. Passare direttamente il markup di cui vengono visualizzate le proprietà, ad esempio "${esperto. Nome}". Questa è una funzionalità ES6 Aurelia in modo da sfruttare, che viene chiamata l'interpolazione di stringa. Stringa interpolazione rende più semplice creare stringhe con variabili incorporate in essi anziché, ad esempio, tramite la concatenazione. Pertanto, con un nome di variabile = "Julie", è possibile scrivere in JavaScript:

`Hi, ${name}!`

e verrà elaborata come "Ciao, Julie!" Aurelia sfrutta interpolazione stringa ES6 e deduce associazione dati unidirezionale quando viene rilevata la sintassi. In modo che ultima riga di codice, a partire da ${esperto. Nome} memorizzeranno le proprietà esperto insieme al resto del testo HTML. Se si crea codice in c# o Visual Basic, vale la pena notare che l'interpolazione stringa è una nuova funzionalità di c# 6.0 e Visual Basic 14.

Necessario apprendere sintassi JavaScript un po' più lungo il percorso, ad esempio la valutazione condizionale della proprietà booleana ServedInOniwaban scopre di avere la stessa sintassi di c#, condizione? true: false.

La formattazione della data che avevo applicato alla proprietà DateOfBirth è un'altra funzionalità Aurelia e può essere familiare se si è utilizzato XAML. Aurelia utilizza convertitori di valori. Desidera utilizzare la libreria JavaScript momento per facilitare la formattazione di data e ora e sto usufruendo di che nella classe format.js data:

import moment from 'moment';
export class dateFormatValueConverter {
  toView(value) {
  return moment(value).format('M/D/YYYY');
  }
}

Tenere presente che è necessario "ValueConverter" nel nome della classe.

Nella parte superiore della pagina HTML, sotto l'elemento iniziale < modello > ottenuto un riferimento al file:

<template>
  <require from="./date-format"></require>

Ora l'interpolazione di stringa è in grado di trovare dateFormat [ValueConverter] nel mio markup e applicarla all'output, come illustrato nella Figura 3.

Visualizzazione di tutti i Ninjas con proprietà associato unidirezionale da Aurelia tramite interpolazione stringa
Figura 3 visualizzazione Ninjas tutte le proprietà associati unidirezionale dal Aurelia tramite interpolazione stringa

Voglio far notare un'altra istanza di associazione in tag div, ma il binding degli eventi, non i dati di associazione. Si noti che nel primo tag di collegamento ipertestuale viene utilizzato una sintassi comune, l'incorporamento di un URL nell'attributo href. Nel secondo caso, tuttavia, non utilizzo href. Utilizzare invece click.delegate. Delegato non è un nuovo comando, ma Aurelia gestirlo in modo speciale che è molto più potente di un gestore dell'evento onclick standard. Ulteriori bit.ly/1Jvj38Z. Continuerò per concentrarsi su dati correlati binding qui.

Portare le icone di modifica a un URL che include l'ID. dell'esperto È stato richiesto il meccanismo di distribuzione per il routing a una pagina denominata Edit.html Aurelia. Questo è associato a un modello di visualizzazione che è in una classe denominato Edit.js.

I metodi più importanti di Edit.js sono per il recupero e salvataggio esperto selezionato. Iniziamo con retrieveNinja:

retrieveNinja(id) {
  return this.http.createRequest("/ninjas/" + id)
    .asGet().send().then(response => {
      this.ninja = response.content;
    });
  }

Questo genera una richiesta simile per la mia API Web come prima, ma questa volta aggiungendo l'id per la richiesta.

Nella classe ninjas.js i risultati è associato a una proprietà di matrice ninjas del mio modello view. Di seguito imposto i risultati, un singolo oggetto alla proprietà esperto del modello di visualizzazione corrente.

Ecco il metodo API Web che verrà chiamato per l'id che viene aggiunto all'URI:

public Ninja Get(int id)
  {
    return _repo.GetNinjaWithEquipmentAndClan(id);
  }

I risultati da questo metodo sono molto più completi rispetto a quelle restituite per l'elenco esperto. Figura 4 viene illustrato il JSON restituito da una delle richieste.

Risultati JSON della richiesta di un esperto di singolo WebAPI
Figura 4 JSON risultati di una richiesta di WebAPI per un singolo esperto

Una volta ho inserito i risultati nel mio modello vista, posso associare le proprietà del bravo agli elementi nella pagina HTML. Questa volta si utilizza il comando .bind. Aurelia deduce se un elemento deve essere associazione unidirezionale o bidirezionale o in altro modo. In realtà, come si è visto in ninjas.html, utilizzata l'associazione flusso di lavoro sottostante quando verrà visualizzata l'interpolazione di stringa. Si è utilizzata l'associazione singolo e unidirezionale. In questo caso, poiché si sta utilizzando il comando .bind e vincola a elementi di input, Aurelia deduce che è possibile l'associazione bidirezionale. Che è la scelta predefinita, che potrebbe eseguire l'override tramite. unidirezionale o un altro comando al posto di .bind.

Per brevità, verrà estratto solo il markup rilevante, anziché gli elementi circostanti.

Di seguito è un elemento di input associato alla proprietà del nome della proprietà esperto nel modello che ho passato nuovamente dalla classe modelview:

<input value.bind="ninja.Name" />

Ed ecco un altro, questa volta associata al campo DateOfBirth. Mi piace che avrei potuto riutilizzare facilmente il convertitore di valori in formato di data anche in questo contesto, utilizzando la sintassi è stato detto in precedenza:

<input  value.bind="ninja.DateOfBirth | dateFormat"  />

Voglio inoltre l'elenco di dispositivi nella stessa pagina, simile a come elencati il ninjas in modo modificate ed eliminate. Per dimostrazione, è andati nella misura in visualizzazione elenco come stringhe, ma non sono implementati la modifica ed eliminare funzionalità né un modo per aggiungere dispositivi:

<div repeat.for="equip of ninja.EquipmentOwned">
  ${equip.Name} ${equip.Type}
</div>

Figura 5 Visualizza il form con l'associazione dati.

Pagina di modifica la visualizzazione dell'elenco di dispositivi
Figura 5 pagina di modifica la visualizzazione dell'elenco di dispositivi

Aurelia ha inoltre una funzionalità denominata associazione adattivo, che consente di adattare le funzionalità di associazione in base alle funzionalità disponibili del browser o anche gli oggetti che vengono passati. È molto interessante e progettato per essere in grado di funzionare insieme ai browser e librerie evoluzione nel tempo. Ulteriori informazioni sul binding adattivo in bit.ly/1GhDCDB.

Attualmente, è possibile modificare solo il nome di esperto, la data di nascita e Oniwaban indicatore. Quando un utente deseleziona servito presente in Oniwaban e preme il pulsante Salva, questa azione chiama il modello di visualizzazione salvataggio metodo, che esegue un'operazione interessante prima di immettere nuovamente i dati per l'API Web. Attualmente, come illustrato nella Figura 4, l'oggetto esperto è un grafico completo. Non è necessario inviare tutto ciò nuovamente per il salvataggio, solo le proprietà rilevanti. Poiché si utilizza Entity Framework a altra estremità, voglio per assicurarsi che le proprietà che non è possibile modificare anche passare in modo che essi non vengono sostituiti con valori null nel database. Sto creando così un DTO in tempo reale chiamato ninjaRoot. Ho già dichiarato ninjaRoot come proprietà del mio modello di visualizzazione. Ma la definizione di ninjaRoot è indicata come costruirò il metodo Save (vedere Figura 6). Sono stato attenti a utilizzare gli stessi nomi di proprietà e distinzione tra maiuscole e previsto dal mio WebAPI in modo è possibile deserializzare questo nel tipo noto esperto nell'API.

Figura 6 Salva metodo nella visualizzazione modello di modifica

save() {
        this.ninjaRoot = {
          Id: this.ninja.Id,
          ServedInOniwaban: this.ninja.ServedInOniwaban,
          ClanId: this.ninja.ClanId,
          Name: this.ninja.Name,
          DateOfBirth: this.ninja.DateOfBirth,
          DateCreated: this.ninja.DateCreated,
          DateModified: this.ninja.DateModified
        };
        this.http.createRequest("/ninjas/")
          .asPost()
          .withHeader('Content-Type', 'application/json; charset=utf-8')
          .withContent(this.ninjaRoot).send()
          .then(response => {
            this.myRouter.navigate('ninjas');
          }).catch(err => {
            console.log(err);
          });
    }

Si noti il metodo "asPost" in questa chiamata. In questo modo, che la richiesta viene inviata al metodo Post nella mia API Web:

public void Post([FromBody] object ninja)
{
  var asNinja =
    JsonConvert.DeserializeObject<Ninja>
    (ninja.ToString());
  _repo.SaveUpdatedNinja(asNinja);
}

Oggetto JSON viene deserializzato in un oggetto esperto locale e quindi passato al mio metodo repository, che è in grado di aggiornare l'oggetto nel database.

Quando si ritorna all'elenco Ninjas sul mio sito Web, la modifica viene riflessa nell'output.

Associazione di più di dati

Tenere presente che Aurelia è un framework molto più completo rispetto per l'associazione dati, ma true se la natura, mi sono concentrato su dati nel mio primi passaggi per esplorare questo strumento. Sono disponibili ulteriori molto sul sito Aurelia Web e una community di fiorente in gitter.im/Aurelia/Discuss.

Si desidera fornire un nodo di grazie al sito Web tutaurelia.net, una serie di blog sulla combinazione di API Web ASP.NET e Aurelia. Inclinato Bart Van Hoey dell'autore parte 6 per il primo passaggio alla visualizzazione dell'elenco di ninjas. Forse al momento che della pubblicazione di questo articolo, verrà aggiunta alla serie altri post.

Download di questo articolo verranno inclusi la soluzione di API Web e il sito Aurelia Web. È possibile utilizzare la soluzione di API Web in Visual Studio. Ho creato, in Visual Studio 2015 utilizzando Entity Framework 6 e Microsoft .NET Framework 4.6. Se si desidera eseguire il sito Web, sarà necessario visitare il Aurelia.io sito per informazioni su come installare Aurelia ed eseguire il sito Web. È possibile anche vedere me dimostrare l'applicazione nel mio corso Pluralsight, "Guida introduttiva con Entity Framework 6," PS/bit.ly-EF6Start.


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 .NET in occasioni di conferenze che si tengono in tutto il mondo. Blog di utente e all'indirizzo indirizzo thedatafarm.com ed è autore di "Programming Entity Framework" (2010), nonché un'edizione di Code First (2011) e un'edizione di DbContext (2012), da o ' Reilly Media. Seguirla su Twitter all'indirizzo /julielerman e vedere i corsi proprio Pluralsight PS/juliel.me-video.*


Grazie all'esperto tecnica seguente per la revisione di questo articolo: Rob Eisenberg (Durandal Inc.)
Rob Eisenberg dispone di dieci anni di esperienza, concentrandosi sull'architettura di interfaccia utente e di progettazione. È il creatore del framework dell'interfaccia utente più quali Caliburn.Micro e Durandal, che sono stati usati da migliaia di sviluppatori in tutto il mondo. Un membro del team 2.0 angolare precedente, Rob lead attualmente il progetto Aurelia, un framework di generazione JavaScript client successivo per dispositivi mobili, desktop e Web che sfrutta le convenzioni semplice per consentire la propria creatività. Ulteriori informazioni su http://aurelia.io/