Connesso al backbone

Ecco la cosa: se non riesci a capire perché avresti bisogno di un framework come Backbone, allora è probabile che tu non lo faccia! Forse stai lavorando esclusivamente su semplici siti web o temi WordPress di base; in questi casi, un framework JavaScript strutturato sarà probabilmente eccessivo.

Tuttavia, arriverà sicuramente un giorno in cui ti rendi conto che tutto quel codice di spaghetti all'interno copione i tag nella parte inferiore della pagina sono diventati improvvisamente ingestibili. Non solo, ma, a causa del modo in cui hai strutturato il tuo codice, è anche impossibile testare. Gasp! Cosa fare?

Quando quel giorno si verifica - e lo farà - punta il tuo browser a Backbonejs.org, e fai un passo avanti, mentre avanzi al livello successivo nella tua maturità di programmazione.


Che cos'è Backbone.js di nuovo?

Pensa a Backbone come a un piccolo framework (5.6kb, ricco) che porta la struttura alle tue applicazioni. Implementando il proprio gusto del pattern MVC (in realtà, più simile a MV *), Backbone fornisce gli strumenti necessari per separare i dati dalla presentazione. Se ci pensi, dove la maggior parte di noi inciampa spesso è quando cerchiamo disperatamente di mantenere i nostri dati. In genere, ciò comporta infinite query DOM, poiché recuperiamo freneticamente i valori necessari per mantenere sincronizzati la presentazione e i dati dell'applicazione. Ci deve essere un modo migliore!

"Ottieni la tua verità dal DOM". - Jeremy Ashkenas (creatore di Backbone.js)

La soluzione, come ideatore di Backbone.js, Jeremy Ashkenas, è spesso invitata a smettere di legare i dati al DOM. Fai in modo che la tua vista rifletta i tuoi dati, non il contrario!


MV *

Sinceramente, probabilmente è meglio se non provi nemmeno a convertire le tue sensibilità MVC esistenti

Vedrai spesso Backbone, così come molti dei suoi framework fratelli, indicati come MV *, piuttosto che MVC. Poiché il concetto di "controller" e "vista" standard lato server non viene trasferito troppo bene a un framework JavaScript, questo può spesso creare confusione. Lo ha fatto sicuramente per me!

Sinceramente, probabilmente è meglio se non provi nemmeno a convertire le tue sensibilità MVC esistenti; ti confonderà solo Una "vista" in Ruby on Rails non è uguale a una "vista" in Backbone. Oppure, un "controller" in CodeIgniter non ha una controparte in Backbone. In realtà, i controller non esistono in Backbone! Invece, Backbone prende a prestito bit e frammenti da altri framework, motivo per cui ci riferiamo spesso ad esso come più vicino a MVP (Model, View, Presenter) o MV *: non è MVC, e nemmeno MVP; è il suo sapore.


Quindi, come funziona?

Iniziamo a determinare come verrà suddivisa la logica nella nostra applicazione. Ridefinire il nostro concetto di come JavaScript dovrebbe essere strutturato può richiedere un po 'di tempo per adattarsi, quindi non preoccuparti se questo richiede tempo per avvolgere la tua mente.

Modelli

In Backbone, i dati sono rappresentati attraverso un modello. Ad esempio, prendi in considerazione a Foto modello. Questo modello definirà il progetto per una foto: qual è la fonte della foto, la sua descrizione, chi è raffigurato nella foto, ecc. Possiamo anche applicare la convalida se necessario, tramite un'opzione convalidare metodo.

var Photo = Backbone.Model.extend (defaults: src: 'images / placeholder.jpg', descrizione: 'My Image', persone: []);

Con il progetto in atto, possiamo ora impostare la nostra prima foto creando una nuova istanza di Foto modello, così:

var photo = new Photo (src: 'images_22 / connected-to-the-backbone.jpg', descrizione: 'Con gli amici a cena', persone: ['John Doe', 'Rick James']);

Tada: hai creato il tuo primo modello. Se hai bisogno di recuperare o impostare informazioni da questa istanza di modello, è facile come usare i getter e setter di Backbone:

photo.toJSON (); // oggetto contenente tutti gli oggetti di scena photo.get ('src'); // images_22 / connected-to-the-backbone.jpg photo.set ('src', 'images / new-path.jpg'); photo.get ( 'src'); // images / new-path.jpg

Visualizzazioni

In Backbone, come best practice, una vista è responsabile della rappresentazione di un singolo elemento DOM e di eventuali bambini applicabili, ad esempio un elemento di elenco o div - quello che vuoi. Ciò include la registrazione di tutti i modelli applicabili, l'ascolto e la risposta agli eventi e il monitoraggio di modelli e collezioni associati per le modifiche.

Creiamo una nuova vista per il tag immagine, stesso.

var ImageView = Backbone.View.extend (tagName: 'img', initialize: function () this.render ();, render: function () this. $ el.attr (src: this.model. get ('src'), alt: this.model.get ('description')););

Non lasciare che questo codice ti confonda. È abbastanza leggibile ed elegante. Lo faremo passo dopo passo.

Iniziare, tagName specifica quale elemento DOM rappresenta la vista. In questo caso, stiamo definendo la vista per un singolo img elemento, tuttavia, avremmo potuto facilmente associarlo a un elemento già esistente nel DOM, tramite il EL proprietà.

var ImageView = Backbone.View.extend (el: '# my-image');

Dietro le quinte, Backbone recupererà l'elemento specificato (# My-immagine) dal DOM, memorizzarlo nella cache e renderlo disponibile, tramite ImageView.el e ImageView. $ El. L'ultima versione, come ci si potrebbe aspettare, è l'elemento racchiuso in jQuery (o potenzialmente Zepto, se si preferisce quella libreria su jQuery).

Successivamente, puoi pensare al inizializzare metodo come costruttore. Quando viene creata una nuova istanza di questa vista, tale metodo verrà eseguito automaticamente. Questo è il posto perfetto per creare nuove variabili di istanza e iscriversi a qualsiasi evento di modello o controller.

Infine, il rendere il metodo è responsabile della costruzione dell'output. In questo caso, imposterà entrambi src e alt attributi dell'immagine uguale al dato che è memorizzato nel modello associato della vista.

Creiamo una nuova istanza di ImageView, e passare alcuni dati. In un'applicazione reale, questi dati potrebbero provenire da un modulo o qualcosa di simile.

var photo = new Photo (src: 'images_22 / connected-to-the-backbone.jpg', descrizione: 'Con gli amici a cena', persone: ['John Doe', 'Rick James']); var imageView = new ImageView (model: photo); imageView.el; // Con gli amici a cena

Questo può essere incredibilmente potente, se ci pensi! In Backbone, è banale aggiornare una vista ogni volta che il rispettivo modello viene alterato, assumendo una relazione uno-a-uno. Ascoltiamo quando i dati (o il modello) vengono modificati. Quando lo è, dovremmo aggiornare l'elemento di conseguenza.

Il seguente codice può essere aggiunto al inizializzare metodo del ImageView.

initialize: function () // Ascolta quando il modello è aggiornato this.model.on ('change', this.render, this); this.render (); , render: function () this. $ el.attr (src: this.model.get ('src'), alt: this.model.get ('description')); 

Non sottovalutare l'efficienza di questa implementazione di PubSub. Quando un modello viene modificato, fa un annuncio, per così dire. "Chiunque sia interessato - Sono appena stato modificato!" A nostro avviso, con una singola riga di codice, possiamo sottoscrivere questo annuncio e rispondere di conseguenza, aggiornando gli attributi dell'immagine.

this.model.on ('change', this.render, this);

In questo caso, richiamiamo il rendere metodo e generare nuovamente gli attributi.

Proviamoci.

var imageView = new ImageView (model: photo); imageView.el; // Con gli amici a cena photo.set ('src', 'images_22 / connected-to-the-backbone.jpg'); imageView.el // Con gli amici a cena

Eccellente! Se è necessario, è anche possibile allegare ascoltatori di eventi a livello di DOM con facilità, tramite un eventi oggetto che Backbone cercherà automaticamente e impostato per te. Forse vuoi modificare l'immagine quando viene cliccato:

eventi: 'clic': 'modifica', modifica: funzione () // modifica l'immagine

Poiché questa particolare vista rappresenta un singolo img elemento, possiamo restare fedeli clic', tuttavia, lo troverai spesso View.el contiene bambini nidificati. In questi casi, puoi specificare un selettore dopo il tipo di evento, in questo modo:

eventi: 'click span': 'doSomething', doSomething: function () 

Il codice sopra, usando View.el come contesto, allegherà un evento click a qualsiasi bambino campataS.

collezioni

A cosa serve un modello per una singola foto? Conserviamo tutti i modelli di foto in a Fotografie collezione. Pensa alle raccolte come a matrici con zucchero aggiunto e metodi di convenienza, grazie all'unico hard-back di Backbone, Underscore.js.

var Photos = Backbone.Collection.extend (model: Photo);

In alto, abbiamo associato il Fotografie collezione con il Foto modello che abbiamo già creato. Ciò specifica che tutti gli elementi di questa raccolta saranno istanze di Foto modello.

Successivamente, creiamo la nostra istanza e passiamo in alcuni modelli per iniziare. In questo caso, stiamo codificando i valori, ma è possibile recuperare il JSON dal server.

var photos = new Photos ([src: 'image1.jpg', descrizione: 'Vacation 2012', src: 'image2.jpg', descrizione: 'My best friend', src: 'image3.jpg' , descrizione: 'Anniversary party']);

Notate come, questa volta, sembra che stiamo semplicemente passando alcuni oggetti al Fotografie collezione. Tuttavia, dietro le quinte, ciascuno oggetto nel schieramento sarà convertito in a Foto modello.

Analogamente ai modelli, le raccolte annunceranno qualsiasi modifica, ad esempio quando un modello viene aggiunto o rimosso. Ciò significa che puoi ascoltare, ad esempio, quando un nuovo oggetto viene aggiunto alla collezione. Quando ciò accade, puoi compensare aggiornando il DOM di conseguenza con il nuovo oggetto.

this.collection.on ('add', this.appendItem);

Inoltre, come notato sopra, una collezione fornisce molto zucchero. Ad esempio, diciamo che abbiamo bisogno di afferrare il src proprietà di tutti i modelli della collezione. Questo è un gioco da ragazzi con il coraggio metodo!

photos.pluck ( 'src'); // ["image1.jpg", "image2.jpg", "image3.jpg"]

Nota come, in ogni momento, i nostri dati sono disponibili. Non dobbiamo mai interrogare il DOM per recuperare alcun valore. "Tieni la verità fuori dal DOM."

Fare riferimento alla documentazione di Underscore.js per ulteriori esempi di utilizzo.

A questo punto, abbiamo una raccolta di foto, ma ora abbiamo bisogno di una nuova vista che sarà responsabile della presentazione del contenitore delle foto. Ricorda, ImageView è responsabile solo per un singolo elemento dell'immagine. Creiamo una nuova vista per l'elenco di wrapping delle foto.

var PhotosView = Backbone.View.extend (tagName: 'ul', className: 'photos', initialize: function () this.render ();, rendering: function () var imageView; this.collection.forEach (function (model) imageView = new ImageView (model: model); this. $ el.append ($ ('
  • ') .html (imageView.el)); , Questo); );
  • Questa volta, stiamo creando la vista per il wrapping

      elemento. Quando chiamiamo render (), il metodo filtrerà attraverso tutti i modelli contenuti nella collezione associata (tre, nel nostro caso), creane uno nuovo ImageView per ciascuno - che costruisce l'elemento dell'immagine - e quindi aggiungiamo quell'elemento immagine generato al .fotografie lista non ordinata.

      Ricorda: non preoccuparti di ridisegni o riflessi. PhotosView.el non è stato ancora iniettato nel DOM.

      photosView.el.parentNode // null

      Quindi mettiamo tutto insieme!

      // Crea una collezione di modelli fotografici. var photos = new Photos ([src: 'image1.jpg', 'description': 'Vacation 2012', src: 'image2.jpg', 'description': 'My best friend', src: ' image3.jpg ',' description ':' Anniversary party ']); // Crea un nuovo PhotosView e passa nella raccolta di foto var photosView = new PhotosView (collection: photos); // Getta la nostra lista di foto nel DOM. . $ ( 'Body') html (photosView.el);

      Ciò può sembrare inizialmente confuso, ma sicuramente diventerà più facile quanto più lavorerai con Backbone. Nel frammento di codice precedente, iniziamo creando una raccolta di Foto Modelli. Successivamente, creiamo una nuova istanza di PhotosView contenitore. Quando viene eseguito il rendering, questa vista filtra attraverso tutti gli elementi della rispettiva collezione, crea nuova ImageView istanze e aggiunge gli elementi risultanti all'elenco non ordinato. Infine, prendiamo il frammento DOM risultante e lo gettiamo nel DOM. Non troppo difficile, eh? E guarda: struttura!


      Letture aggiuntive

      Abbiamo appena graffiato la superficie di ciò che è in grado di Backbone. Per continuare il tuo apprendimento, fai riferimento ai seguenti libri, screencast ed esercitazioni.

      • Hello Backbone.js (Tutorial)
      • Backbone Fundamentals (eBook)
      • Informazioni su Backbone in .NET (corso)
      • Hands-On Backbone.js (Screencast)
      • Backbone.js + CoffeeScript (eBook)
      • The Anatomy of Backbone.js (Corso)

      Conclusione

      La spina dorsale è a volte criticata per non offrire abbastanza. Non applica alcuna struttura particolare e non offre componenti dell'interfaccia utente che potresti ricevere dall'interfaccia utente di Dojo o jQuery. Ironicamente, nonostante queste critiche, questo è ciò che rende Backbone così fantastico. Non impone le sue opinioni su di te. Fa un lavoro e un lavoro magnificamente: fornisce una struttura per le tue applicazioni. Sei quindi libero di capire come meglio adattare Backbone ai tuoi progetti esistenti.