Bentornati al Costruire un visualizzatore di contenuti con Backbone serie. Nelle prime quattro parti, abbiamo esaminato quasi tutti i principali componenti forniti con l'ultima versione di Backbone inclusi modelli, controller, viste e router.
In questa parte del tutorial, collegheremo la nostra applicazione a un server Web in modo che possiamo memorizzare i nostri contatti in un database. Non guarderemo LocalStorage; questo è un mezzo popolare per mantenere i dati utilizzati dalle app Backbone, ma il fatto è che ci sono già un numero di tutorial eccellenti disponibili su questo argomento.
Avremo bisogno di un server web e di un database per questa parte del tutorial. Io uso il VWD di Microsoft come editor, che viene fornito con un server web integrato e funziona bene con il server MSSQL, quindi questo è quello che useremo. In realtà, non importa quale pila si decide di andare con.
L'installazione e la configurazione di una di queste tecnologie (server VWD e MSSQL) va oltre lo scopo di questo tutorial, ma è relativamente semplice da fare e ci sono un sacco di buone guide là fuori.
Una volta installato, ti consigliamo di impostare un nuovo database contenente una tabella in cui archiviare i dati. Le colonne della tabella dovrebbero rispecchiare le diverse proprietà utilizzate dai nostri modelli, quindi dovrebbe esserci una colonna nome, una colonna indirizzo, ecc. può essere popolato con i dati di esempio che abbiamo utilizzato finora nella serie.
Una colonna che dovrebbe apparire nella nostra nuova tabella, ma che non abbiamo usato nei nostri dati di test locali è un id
, che dovrebbe essere unico per ogni riga nella tabella. Per facilità d'uso, probabilmente si desidera impostare l'auto-incremento quando i dati vengono aggiunti alla tabella.
Per comunicare con il server, Backbone ci fornisce il Sync
modulo; questo è l'unico modulo principale che non abbiamo ancora usato e quindi comprenderlo completerà la nostra conoscenza dei fondamenti del framework.
Chiamando il sync ()
il metodo produce una richiesta al server; per impostazione predefinita, presuppone che jQuery o Zepto siano in uso e delega la richiesta a qualsiasi di esse sia effettivamente presente. Presuppone anche che un'interfaccia RESTful sia in attesa sul back-end, quindi per impostazione predefinita utilizza i metodi POST, PUT, GET, DELETE HTTP. Come abbiamo visto, Backbone può essere configurato per ricorrere ai metodi GET e POST della vecchia scuola con intestazioni aggiuntive che specificano l'azione desiderata.
Oltre a poter chiamare sync ()
direttamente, modelli e collezioni hanno anche metodi che possono essere usati per comunicare con il server; i modelli hanno il distruggere()
, fetch ()
, parse ()
e salvare()
metodi e collezioni hanno fetch ()
e parse ()
. Il distruggere()
fetch ()
e sync ()
metodi tutti rimandano a sync ()
se usato con modelli o collezioni. Il parse ()
metodo, chiamato automaticamente ogni volta che i dati vengono restituiti dal server, è di default un semplice no-op che restituisce solo la risposta dal server, ma può essere sovrascritto se si desidera pre-elaborare la risposta prima di consumarla.
Il modo in cui i dati del modello vengono caricati nella pagina varia in base alla tecnologia di back-end utilizzata.
La documentazione Backbone per il fetch ()
metodo (di una raccolta) afferma che questo metodo non deve essere utilizzato sul caricamento iniziale della pagina per richiedere i modelli richiesti dal server. Continua a elaborare nella sezione Domande frequenti che una pagina deve avere i moduli richiesti già disponibili per la pagina in caricamento per evitare la richiesta iniziale AJAX.
Questa è una grande idea e anche se non dovremmo seguire esplicitamente il consiglio, così facendo renderemo la nostra applicazione un po 'più snella, e questa può essere solo una buona cosa.
Il modo in cui i dati del modello vengono caricati nella pagina varia in base alla tecnologia di back-end utilizzata. In questo esempio useremo .net, quindi un modo per farlo sarebbe creare dinamicamente a element containing the required model data, and inject it into the page. To do this we'll need to convert our
index.html
file to index.aspx
instead (we'll also need an index.aspx.cs
code-behind or class file too). But doing this raises a new issue.
We can lift the 'Mustache-style' example straight off of the Underscore documentation page.
The problem with Underscore templates is that they use <%=
to specify placeholders in the template that are replaced with actual data when the template is consumed. This is the same syntax that ASPX pages use to run dynamic .Net code within HTML tags. The Underscore templates that we've used in this example so far prevent the ASPX page from running correctly and instead it displays a server error.
Fortunately there are several ways around this problem, the simplest way being to change the syntax used to specify the placeholders used in the templates. Underscore exposes the templateSettings
property for this very purpose, allowing us to easy specify a regular expression used to match the symbols we wish to use. We can lift the 'Mustache-style' example straight off of the Underscore documentation page in fact; at the start of our app.js
file (within the very outer function) we can just add the following code:
_.templateSettings = interpolate: /\\(.+?)\\/g ;
All this does is supply a new regular expression to the interpolate
method, which allows us to use the alternative syntax property
instead of <%= property %>
. We should also at this point go through the templates and change all of the original template tags to use the new syntax.
Although this is not something we've used in our templates so far, there are also additional symbols that Underscore can use. We can evaluate JavaScript using <%
and can escape data using <%-
. If we wish to use these in our templates and have replaced the interpolate
property, we should also configure the evaluate
and escape
Underscore properties as well.
We can now think about delivering the model data that is stored in a database to our page when the page is initially rendered. We can easily do this be adding a simple method to the class file for our ASPX page that reads the records from the database and creates a list of objects where each object represents a single contact. We can then serialise the list into a JavaScript array and inject it into the page. As long as the array has the same format as the dummy array we used in the first four parts of this tutorial, we won't have to change our front-end code.
As a placeholder for the array, we can just add a new element to the body of the page, directly before the reference to
app.js
, which calls the method in the code-behind:
La logica effettiva nel code-behind che esegue la lettura del database e la serializzazione dell'elenco potrebbe variare in modo selvaggio a seconda dell'implementazione ed è in qualche modo oltre lo scopo di questo tutorial: siamo più interessati a ottenere il payload iniziale sulla pagina di quello che siamo su come effettivamente lo prendiamo. Sentiti libero di dare un'occhiata al file di classe nel download del codice allegato, probabilmente il modo più veloce e semplice, ma non il migliore, per farlo.
A questo punto, dovremmo essere in grado di rimuovere l'array di contatti da cui sono stati archiviati i nostri dati fittizi app.js
, eseguire la pagina (tramite il web server WVD integrato, o IIS) e vedere esattamente la stessa pagina, con quasi la stessa funzionalità, come abbiamo visto alla fine della parte 4. Yay!
In questo esempio, ho usato un file ASMX. NET 4.0 per gestire le richieste dal front-end. Affinché il back-end visualizzi i dati inviati, dovremmo configurare il emulateHTTP
e emulateJSON
Proprietà backbone. Aggiungi le seguenti righe di codice direttamente dopo la modifica della sintassi del template di Underscore:
Backbone.emulateHTTP = true; Backbone.emulateJSON = true;
Indipendentemente dal fatto che sia necessario configurare queste proprietà quando si costruisce un'applicazione Backbone per reale dipende interamente dalla tecnologia di back-end scelta per lavorare con.
Quindi, la nostra applicazione potrebbe modificare i dati in diversi modi; potrebbe cambiare gli attributi di un contatto già esistente, potrebbe aggiungere un contatto completamente nuovo, oppure potrebbe eliminare un contatto già esistente.
La logica per fare tutte queste cose sul front-end esiste già, ma ora che è coinvolto un server, il comportamento della pagina è già cambiato. Sebbene la pagina esegua il rendering come prima, se proviamo a eliminare un contatto, Backbone genererà un errore che si lamenta del fatto che un URL non è stato definito. La ragione di questo è perché abbiamo usato il distruggere()
metodo nel deleteContact ()
metodo del nostro ContactView
classe.
Diamo un'occhiata a come ripristinare la funzionalità di eliminazione. La prima cosa che dovremmo fare è definire a url
attributo per i nostri modelli. Aggiungi la proprietà al Contatto
classe che definisce un singolo modello:
url: function () return "/ContactManager.asmx/ManageContact?id=" + this.get ("id");
Specifichiamo una funzione come valore del url
proprietà, che restituisce l'URL che dovrebbe essere usato per fare le richieste a. In questo esempio, possiamo utilizzare un file di servizio Web asmx per gestire le richieste. Aggiungiamo anche il nome del nostro metodo web (ManageContact
) e aggiungere il id
del modello come parametro della stringa di query.
Ora se cancelliamo uno dei contatti quando eseguiamo la pagina viene effettuata una richiesta POST al servizio web. Un X-HTTP-Metodo-override
l'intestazione viene aggiunta alla richiesta che specifica che il metodo HTTP previsto era ELIMINA
. Possiamo usarlo nella nostra logica del servizio web per determinare quale azione intraprendere sul database.
Successivamente possiamo aggiornare il saveEdits ()
metodo del ContactView
classe in modo che notifichi il servizio Web quando viene modificato un contatto; cambia la linea di codice che usa il impostato()
metodo in modo che appaia così:
this.model.set (formdata) .save ();
Tutto ciò che facciamo è concatenare il salvare()
metodo sul impostato()
metodo. Il salvare()
metodo delegato al sync ()
metodo che effettua una richiesta POST al server. Come prima il id
del modello viene inviato come stringa di query e un X-HTTP-Metodo-override
è usato per specificare il metodo PUT previsto. Questa volta tuttavia, il Tipo di contenuto
l'intestazione è impostata su application / x-www-form-urlencoded
(se non abbiamo configurato il emulateJSON
proprietà sarebbe application / json
) e i dati del modello vengono inviati come dati di un modulo, che possiamo utilizzare per apportare le modifiche necessarie.
Tutto ciò che resta da fare sul front-end è aggiornare il Agg.contatto ()
metodo del DirectoryView
classe. Precedentemente in questo metodo avevamo un'istruzione if che controllava il tipo del modello che veniva aggiunto per vedere se il menu di selezione doveva essere aggiornato. Dovremmo ora cambiarlo se l'istruzione in modo che appaia come segue:
if (_.indexOf (this.getTypes (), formData.type) === -1) this. $ el.find ("filtro #"). find ("select"). remove (). end () .Append (this.createSelect ()); this.collection.create (formData);
Abbiamo tagliato il Se
dichiarazione giù per rimuovere il altro
condizione, rendendo il codice un po 'più ordinato. Abbiamo anche rimosso il Inserisci()
metodo e aggiunto il creare()
metodo al suo posto. Il creare()
il metodo aggiungerà automaticamente il nuovo modello alla raccolta automaticamente senza che noi creiamo manualmente una nuova istanza della classe del nostro modello e farà anche una richiesta al server, ancora una volta delegando a sync ()
.
Questa volta il X-HTTP-Metodo-override
non è necessario impostare l'intestazione, perché POST è il metodo che useremmo se la richiesta fosse fatta a un'interfaccia RESTful comunque. Come con il salvare()
metodo, i dati del modello passati al creare()
il metodo viene consegnato al server come dati del modulo.
Come con il codice lato server utilizzato all'inizio di questa parte del tutorial per eseguire il bootstrap dei dati del modello iniziale nella nostra app, il codice utilizzato per elaborare e gestire le richieste fatte da Backbone va oltre lo scopo del tutorial. Siamo interessati solo al front-end qui. Come prima, il servizio Web utilizzato per questa demo è incluso nell'archivio del codice ed è completamente commentato, quindi controlla se sei interessato. Ho anche incluso un backup del database, che dovresti essere in grado di ripristinare per andare avanti con i dati demo.
In questa parte del tutorial, abbiamo esaminato alcuni dei metodi che è possibile utilizzare per delegare a Backbone sync ()
metodo per comunicare con un back-end che può mantenere le modifiche apportate utilizzando il front-end dell'applicazione.
Abbiamo visto come Backbone per impostazione predefinita rende le richieste RESTful a un URL specificato e come possiamo configurarlo per lavorare con server legacy che non funzionano sui principi REST. Abbiamo anche esaminato alcuni dei metodi che delegano a sync ()
per comunicare con il server. In particolare, abbiamo coperto il rimuovere()
, salvare()
e creare()
metodi e guardato ciò che viene inviato al server e come.
Abbiamo anche osservato quanto sia facile cambiare i simboli utilizzati da Underscore per interpolare i dati in un modello. Questo ora conclude il tutorial di Contact Manager; mentre ci sono molte altre funzionalità che potremmo aggiungere all'applicazione, ora abbiamo coperto le basi di ciò che serve per costruire un'applicazione pienamente funzionale usando l'eccellente Backbone.js. Grazie per aver letto.