Quindi hai accettato la sfida di diventare grossa sul lato client; molto bene. Hai considerato tutti i framework là fuori e non sei sicuro di quale scegliere? Non sei solo. Continuare a leggere.
La mia esperienza, quando ho imparato il modo di scrivere applicazioni lato client, si sta rivelando difficile e difficile. Non è facile scegliere deliberatamente di usare MV *
sul client per qualcuno che ha scritto JavaScript, basato interamente su jQuery e sui suoi plugin. Questo è un paradigma completamente nuovo; richiede competenze di programmazione di base e una notevole conoscenza del design di JavaScript (il linguaggio). Se la tua esperienza riguarda la mia, allora continua a leggere!
Illustrerò le principali differenze tra due dei più popolari framework clientide JavaScript: Backbone.js ed Ember.js. Ciascuno di questi strumenti ha punti di forza, così come punti deboli che potrebbero aiutarti a fare una scelta più riflessiva.
Disclaimer: come professionisti del software, dobbiamo affrontare la diversità di opinione. Backbone e Ember sono risultati di professionisti esperti ed esperti, come me e te. Uno strumento non è migliore dell'altro; servono solo folle diverse e, ergo, risolvono problemi diversi. Grazie Trek per i solidi consigli.
Backbone è molto più facile da imparare di Ember.
Innanzitutto, è necessario capire che Backbone ed Ember servono in particolare folle leggermente diverse. Per quanto riguarda la complessità, Backbone è molto più facile da imparare rispetto a Ember. Tuttavia, si dice che una volta che si impara Ember, difficilmente diventa più complesso. Prendi la parola di Trek su di esso. Se hai appena iniziato con qualche vero JavaScript, allora forse Backbone è il tuo strumento. Se, tuttavia, sai che dovrai affrontare molto più di un semplice caso d'uso o due, allora potresti preferire l'Ember.
Jeremy Ashkenas ha costruito Backbone in modo che fosse possibile togliere la verità dal DOM
. Ciò che intende con questo è: qualsiasi attività che hai fatto usando solo jQuery / Mootools / Prototype potrebbe e dovrebbe essere meglio estratta in pure strutture JavaScript - oggetti, se vuoi. Invece di usare DOM
elementi per definire gli elementi e il comportamento del tuo business, Backbone ti invita a farlo al contrario. Gli oggetti JavaScript sono il nucleo e il DOM
è semplicemente una rappresentazione di quei dati.
Con Backbone, hai alcune affermazioni date:
DOM
Hai il controllo completo sul modo in cui costruisci la tua app. Backbone aveva lo scopo di darti un modo basilare per progettare i tuoi oggetti modello e come questi interagissero tra loro attraverso i binding di eventi.
Rendering HTML
al DOM
è di tua responsabilità. Sei libero di scegliere qualsiasi motore di template: Moustache, DoT, Handlebar, Underscore, ecc. Backbone contiene a vista
prototipo che ha la responsabilità di articolare il DOM
e il tuo nucleo di JavaScript.
Quando Tilde ha iniziato a costruire Ember, lo ha fatto con un obiettivo molto più impegnativo: a fornire convenzioni standard nello sviluppo lato client, eliminando il maggior numero possibile di piastre. Il risultato è un quadro molto più ambizioso che mira a un'architettura prevedibile ea uno sviluppo costante.
Ember condivide alcuni punti comuni con Backbone nel modo in cui cerca di estrarre dati e comportamenti dal DOM
fornendo prototipi estensibili di JavaScript, ma lo fa in un modo molto diverso da quello di Backbone.
Ember si leva in piedi su:
Sia Backbone che Ember hanno concetti chiave comuni, come visualizzazioni. Entrambi rappresentano DOM
comunicazione, rispettivamente. Il modo in cui realizzano questo concetto sono in qualche modo diversi, però.
Userò il caso d'uso di Todo per gli esempi di seguito, ispirato alla vetrina di TodoMVC.
Una vista Backbone potrebbe essere qualcosa del genere:
var TaskView = Backbone.View.extend (tagName: "li", modello: "modello-attività", render: function () // il codice da mostrare qui., events: "click .mark-done" : "mark_as_done", "change .body": "update_body", mark_as_done: function () / * codice qui * /, update_body: function () / * code here * /);
Questa è semplicemente la definizione della tua vista. Sarà necessario istanziarne uno se si desidera che sia nella pagina. Qualcosa di simile farà il trucco:
var task_view = new Task (model: task_model); . $ ( "Corpo") append (task_view.el);
Si noti che stiamo passando un modello in modo da poter mantenere un riferimento all'oggetto dati che alimenta il modello. Il modello
la proprietà all'interno della vista può essere utilizzata per chiamare un modello esterno, tramite un identificatore. Ho usato qualcosa del genere in passato:
var TaskView = Backbone.View.extend (template: "# task-template", render: function () this. $ el.html (Moustache.render ($ (this.template) .html ()), this. modello); // snip);
Ember ha un approccio diverso alle visualizzazioni. In effetti, la convenzione afferma che le visualizzazioni dovrebbero parlare direttamente con i controller e non con i modelli. Questa è una buona pratica, se intendi seguire un'architettura stabile. Spiegherò l'esempio per la stessa vista:
var TaskView = Ember.View.extend (templateName: "modello-attività", mark_as_done: function () / * codice qui * /, update_body: function () / * code here * /);
Questo è tutto. Ma dov'è tutta la roba di rendering? Bene, Ember solleva quella caldaia per te. Dì semplicemente che cos'è il modello, il controller che detiene l'oggetto dati, e quindi devi solo aggiungerlo al DOM
.
var task_view = TaskView.create (controller: task_controller // Ember.ObjectController); task_view.append ();
Quando si crea una nuova istanza di visualizzazione, si vincolerà il contenuto del controller (che può essere un Ember.Object
o un elenco di loro) alla vista. Quando decidi di aggiungere la vista al DOM
, cercherà il modello e inserirà il markup generato per te.
Backbone è più esplicito e meno magico.
Backbone è più esplicito e meno magico. Tu crei a vista
, digli quale modello usare e come, registra gli eventi e fai ciò che devi fare. Loro possiedono la pagina. Questo è un ottimo inizio per coloro che provengono da uno sfondo jQuery. Tuttavia, quando qualcosa deve essere aggiornato nel DOM
, affronterai qualche piastra di riscaldamento.
Con Ember, gli aggiornamenti sono automatici. Tu dici quale modello è e le callback degli eventi sono funzioni all'interno dell'oggetto vista. Ogni volta che un oggetto viene aggiornato, la vista aggiorna automaticamente la pagina.
Alcuni binding di eventi comuni sono incorporati in Ember e altri devono essere inseriti nel modello. È buono per coloro che provengono da una prospettiva di back-end, in quanto riduce in modo considerevole il boilerplate.
I modelli in Backbone e Ember sono abbastanza simili. Tengono informazioni per un'entità commerciale.
Un esempio di un modello Backbone si presenta così:
var TaskModel = Backbone.Model.extend ();
Con questa semplice linea di codice, hai un modello funzionante con RIPOSO
piena comunicazione integrata. Hai metodi come salvare
per mantenere i dati e andare a prendere
caricarlo gratuitamente; non è richiesto alcun plug-in. La validazione è anche incorporata nel modo in cui i dati vengono salvati fornendo un convalidare
callback, che restituisce un valore booleano che indica il record da salvare o meno. L'implementazione della convalida è ancora a disposizione dello sviluppatore.
Per creare una nuova attività, puoi creare un'istanza nuova taskModel
.
var task = new TaskModel (body: "Mow the lawn", done: false);
È possibile iniettare tutti gli attributi che si desidera, poiché l'elenco degli attributi dell'attività non è rigido (pensatelo come schemaless). Puoi ancora impostare a default
proprietà durante l'estensione Backbone.Model
.
Con Ember, non ci sono modelli, solo oggetti. Potrebbe sembrare qualcosa del genere:
var TaskObject = Ember.Object.extend ();
Simile a Backbone, è necessario estendere da Ember.Object
per creare una classe di oggetti. Esso eredita tutte le funzionalità di base di una classe con callback per quando viene modificato, creato e distrutto, tra le altre caratteristiche. Tuttavia, non ha la comunicazione di back-end fuori dalla scatola. Ember.Data
è in fase di sviluppo come estensione di Ember.Object
dal team di base Ember per soddisfare tale esigenza. È già utilizzabile ma non stabile per quanto riguarda la documentazione.
Si considerano anche oggetti di brace schemaless. Per iniettare i valori predefiniti in oggetti Ember, estendi Ember.Object
passando un oggetto con tutti gli attributi che desideri.
var TaskObject = Ember.Object.extend (body: "Mow the lawn", done: false);
Backbone ha un modo consolidato di sincronizzarsi con un livello di persistenza finito RIPOSO
e questa è una buona convenzione lì. È una cosa in meno che devi configurare per lavorare con un server di backend.
Ember si sta facendo strada verso la realizzazione Ember.Data
pronto per l'uso produttivo e sembra promettente. Anche così, la particolarità degli oggetti Ember che hanno collegamenti bidirezionali rende facile la connessione tra oggetti.
A questo punto della tua lettura, hai un punto di flesso tra la stabilità di Backbone nella comunicazione con il server di backend e le associazioni di Ember. Qualunque cosa sia più importante per te dovrebbe determinare la tua decisione.
Questo è dove i quadri si separano. Hanno un enorme vuoto concettuale su come incollare le cose insieme nella tua app. Mentre Backbone si sforza di rimanere il più semplice e flessibile possibile, Ember sacrifica le dimensioni del codice base per una migliore architettura. È un compromesso, davvero.
Attenzione: i seguenti esempi non contengono esempi di template HTML.
Come ho notato, Backbone punta alla semplicità che si converte in flessibilità e raggiunge tali attributi con precisione la mancanza di una classe di controller. La maggior parte del cavallo di battaglia è distribuito su viste, collezioni, modelli e router (se si sceglie di utilizzare Backbone Router
).
Considerando un elenco di attività che devono essere gestite, richiederebbe:
Collezione
per memorizzare i compiti.Modello
per memorizzare le informazioni di un'attività.vista
per rappresentare la collezione.vista
per rappresentare ogni attività.Router
per gestire gli URL.La maggior parte della logica applicativa vivrà nelle visualizzazioni, in quanto connettono i modelli al DOM
. Non c'è una chiara distinzione delle responsabilità, poiché la visione fa tutto. Può essere utile per le piccole applicazioni che non richiedono un'architettura solida.
Per visualizzare un elenco di attività, si otterrebbe qualcosa del genere:
var TaskList = Backbone.Collection.extend (model: Task);
var TaskModel = Backbone.Model.extend ();
var TaskListView = Backbone.View.extend (rendering: function () this. $ el.empty (); for (_i = 0, _i < this.collection.length; _i++) var task = this.collection.models[_i]; this.$el.append(this.renderItem(task)); var tasks = this.$el.html(); this.$el.html(Mustache.to_html(template, tasks: tasks, no_tasks: !this.collection.length )); , renderItem: function(task) var view = new Row( model: task ); var el = view.render(); return el.el; , );
var TaskView = Backbone.View.extend (tagName: "tr", render: function () this. $ el.html (M.to_html (template, this.model.attributes)); restituisci questo;);
var Router = Backbone.Router.extend (initialize: function () this.tasks = new TaskList; this.view = new TaskListView (collection: this.tasks);, routes: "": "tasks_list" ,, tasks_list: function () this.view.render (); $ (". bucket: first"). html (this.view.el);, start: function () Backbone.history.start ( pushState: true, root: "/ ticket /"););
Si noti che la raccolta non ha un proprio modello; piuttosto, delega a una singola vista di attività che viene renderizzata e accodata al risultato finale inserito nella pagina.
Il numero di classi richiesto per avere la stessa configurazione è leggermente più grande.
Collezione
, avresti un ArrayController
, che funziona molto allo stesso modo.ObjectController
per la gestione di una singola attività. Modello
, avresti un Oggetto
/ DS.Model
, che funzionano allo stesso modo.vista
S.Router
è anche responsabile della gestione degli URL.Potresti pensare che i due quadri non siano troppo diversi l'uno dall'altro. È piuttosto allettante, ma non è esattamente vero. Alcune differenze particolari sono:
DOM
, non il controller.La separazione delle preoccupazioni è buona a lungo termine. Il controller gestisce i dati, le viste gestiscono il DOM
, periodo. Questo tipo di design disaccoppiato e coesivo, senza caldaia, consente una testabilità più mirata.
L'implementazione per visualizzare lo stesso elenco di attività sarebbe simile alla seguente, considerando un'applicazione Ember completa:
window.App = Ember.Application.create (); App.ApplicationController = Ember.ObjectController.extend (); App.ApplicationView = Ember.View.extend (templateName: "application");
App.Task = Ember.Object.extend ();
App.TasksController = Ember.ArrayController.extend (content: []);
App.TasksView = Ember.View.extend (templateName: "my-list");
App.Router = Ember.Router.extend (root: Ember.Route.extend (index: Em.Route.extend (route: '/', connectOutlets: function (router) router.get ('applicationController') .connectOutlet ('tasks');));
Nel caso di Ember, non si dice molto su come si fanno le cose all'interno. Tutto ciò che viene fornito viene portato via così puoi concentrarti su ciò che conta davvero nella tua app: definisci un oggetto compito, un controllore dell'elenco compiti con un array chiamato soddisfare
, la tua vista e il router li combina semplicemente tutti insieme e li inserisce nella pagina.
Dopo aver capito come funziona davvero Ember, inizia a diventare liberatorio.
Prevedibilmente, questo segmento è stato il più difficile da comprendere su entrambi i quadri. Backbone è stato sicuramente più facile da imparare e la sua natura flessibile dà il controllo sul modo in cui gli oggetti e DOM
interagire. Questo potrebbe essere utile per te, se hai davvero bisogno di quel tipo di flessibilità ma vuoi comunque mantenere una struttura per la logica della tua app nel lato JavaScript.
Per quanto riguarda Ember, la sua implementazione mozzafiato potrebbe essere spaventosa all'inizio. Tuttavia, dopo aver capito come funziona davvero Ember, inizia a diventare liberatorio. Tutte le convenzioni che il framework impone per te ti liberano dal boilerplate e dalla configurazione, permettendoti di concentrarti sulla tua app. Questo è simile a quello che ha fatto Rails per lo sviluppo serveride che ha catturato così tanta attenzione.
Ember aveva lo scopo di sollevare gli oneri comuni dello sviluppo di JavaScript nel browser.
Finora, il punto principale di mostrare i due strumenti è stato quello di riconoscere il loro unico e nobile scopo: delegare energia dal lato del cliente, attraverso sia la struttura che il metodo.
Il punto di forza del backbone è sicuramente il suo approccio KISS. Ti fornisce il minimo per lasciar andare il DOM
come principale sostenitore della tua app e inizia a utilizzare oggetti JavaScript reali che possono essere testati e progettati correttamente.
Backbone è ricco di collezioni, modelli, viste e router, tra le altre piccole utility. Sei libero di fare ciò che ti piace con loro.
Ember, d'altra parte, è stato costruito con una mentalità diversa, in quanto mira a un modo molto più convenzionale e convinto di costruire applicazioni web. Affronta una serie di problemi comuni, come il boilerplate, l'associazione dei dati e DOM
per cui non devi preoccuparti di loro fin dall'inizio. Ember aveva lo scopo di sollevare gli oneri comuni dello sviluppo di JavaScript nel browser.
Ember è pieno di oggetti, controller, visualizzazioni autoaggiornanti, macchine a stati, associazioni, osservatori e un router (che è anche una macchina a stati), tutti evocati con una buona dose di convenzioni. Hai un'architettura già progettata e pronta per iniziare a lavorare senza perdere la concentrazione.
Ricorda il divario di apprendimento. La tua esperienza e il tuo patrimonio culturale determineranno con forza la velocità con cui ti unisci al cliente. Se hai paura di cosa fare o quale scegliere, allora ho colpito un tuo nervo e va bene! Vuoi una buona risposta su cui scegliere? Tutti e due.
Se non sei sicuro di come jQuery fa tutta la sua magia, allora inizia ad imparare Backbone. È più facile iniziare e la documentazione è semplice da leggere e capire. Dopo aver finito, inizia a costruire qualcosa. Sporca Consulta questi tutorial se hai bisogno di aiuto.
Se sei ancora al buio, leggi le voci di Yehuda Katz su come funziona JavaScript.
Una volta ottenuta una visione migliore di come funziona JavaScript come lingua, inizierai a capire meglio come gli oggetti interagiscono tra loro. Quando lo fai, vai per Ember. All'inizio è più complicato, ma non arrenderti. Inizia a leggere i documenti e le guide. Potresti voler controllare il blog di Trek Glowacki prima di sporcarti le mani.
Personalmente, mi sto appoggiando ad Ember; Mi piace la sua robustezza su scala macro, e preferisco anche le sue convenzioni. Backbone è uno strumento più malleabile e più semplice per le app più piccole o per le piccole funzionalità all'interno di un'app esistente.
Sto ancora imparando entrambi e ho alcune sfide da affrontare:
Quali sono i tuoi pensieri su questa intera debacle? Hai qualche problema in mente? Qualche difficoltà o impedimento? Fammi sapere!