Așa că ați acceptat provocarea de a deveni groasă pe partea clientului; foarte bine. V-ați gândit la toate cadrele existente și nu sunteți siguri pe cine să alegeți? Nu esti singur. Citește mai departe.
Experienta mea, atunci cand invatam modul de scriere a aplicatiilor pe partea clientului, se dovedeste a fi abrupta si grea. Nu este ușor să alegeți în mod deliberat să utilizați MV *
pe client pentru cineva care a scris JavaScript, bazat exclusiv pe jQuery și plugin-urile sale. Aceasta este o paradigmă cu totul nouă; necesită abilități de programare de bază și o înțelegere considerabilă a designului JavaScript (limba). Dacă experiența dvs. se referă la a mea, citiți mai departe!
Voi explica principalele diferențe dintre două dintre cele mai populare cadre client JavaScript: Backbone.js și Ember.js. Fiecare dintre aceste instrumente are puncte forte, precum și puncte slabe care vă pot ajuta să alegeți mai atent.
Disclaimer: ca profesioniști în domeniul software-ului, trebuie să ne ocupăm de diversitatea opiniei. Backbone și Ember sunt rezultate ale unor profesioniști cu experiență și cu experiență, precum dumneavoastră și cu mine. Un instrument nu este mai bun decât celălalt; ele servesc doar mulțimi diferite și, ergo, rezolvă diferite probleme. Mulțumesc Trek pentru sfatul solid.
Spinele este mult mai ușor de învățat decât Ember.
În primul rând, trebuie să înțelegeți că Backbone și Ember servesc mai ales mulțimi puțin diferite. În ceea ce privește complexitatea, Backbone este mult mai ușor de învățat decât Ember. Cu toate acestea, se spune că, odată ce ați învățat Ember, cu greu nu mai devine mai complexă. Luați cuvântul lui Trek pe el. Dacă începeți doar cu un anumit JavaScript real, atunci poate Backbone este instrumentul dvs. Dacă, totuși, știți că veți avea de-a face cu mult mai mult decât un simplu caz de utilizare sau două, atunci ați putea prefera Ember.
Jeremy Ashkenas a construit Backbone astfel încât ar fi posibil să scoate adevărul din DOM
. Ceea ce vrea sa spuna prin aceasta este: orice afacere pe care ai facut-o folosind doar jQuery / Mootools / Prototype ar putea si ar trebui sa fie mai bine extrasa in structuri JavaScript - obiecte, daca vrei. În loc de a folosi DOM
elemente pentru a defini elementele de afaceri și comportamentul dvs., Backbone vă invită să o faceți invers. Obiectele JavaScript sunt nucleul și DOM
este doar o reprezentare a acestor date.
Cu Backbone, aveți câteva afirmații:
DOM
Vi se oferă control complet asupra modului în care construiți aplicația. Backbone a fost menit să vă ofere o modalitate de bază de proiectare a obiectelor dvs. de model și a modului în care acestea interacționează între ele prin legarea evenimentului.
Redare HTML
la DOM
este de responsabilitatea dvs. Aveți libertatea de a alege orice motor de șablon: Mustache, DoT, Handlebars, Underscore etc. Backbone conține o Vedere
prototip care are responsabilitatea de a articula DOM
și nucleul dvs. JavaScript.
Când Tilde a început să construiască Ember, a făcut acest lucru cu un scop mult mai provocator: să să ofere convenții standard în dezvoltarea clientului, eliminând cât mai mult posibil. Rezultatul este un cadru mult mai ambițios care vizează o arhitectură previzibilă și o dezvoltare constantă.
Ember împărtășește câteva puncte comune cu Backbone în modul în care încearcă să tragă date și comportament din DOM
prin furnizarea de prototipuri JavaScript extensibile, dar face acest lucru într-o manieră foarte diferită de cea a Backbone-ului.
Ember se află pe:
Atât Backbone cât și Ember au concepte cheie comune, cum ar fi vizualizari. Ambele reprezintă DOM
comunicare, respectiv. Modul în care realizează acest concept sunt oarecum diferite.
Voi folosi cazul de utilizare Todo pentru exemplele de mai jos, inspirat de prezentarea TodoMVC.
O vizualizare backbone ar putea fi ceva de genul:
var TaskView = Backbone.View.extend (tagName: "li", șablon: "task-template", render: function () : "mark_as_done", "change .body": "update_body", mark_as_done: function () / * cod aici * /, update_body: function () / * cod aici * /);
Aceasta este pur și simplu definiția părerii tale. Va trebui să instanțiați unul dacă doriți să fie în pagină. Ceva de genul asta va face truc:
var task_view = task nou (model: task_model); . $ ( "Corp") append (task_view.el);
Observați că trecem un model în așa fel încât să puteți păstra o referință la obiectul de date care alimentează șablonul. șablon
proprietatea din interiorul vizualizării poate fi utilizată pentru a apela un șablon exterior, printr-un identificator. Am folosit ceva de genul asta în trecut:
var TaskView = Backbone.View.extend (template: "# task-template", render: function () this. $ el.html (Mustache.render ($ (this.template) model); // snip);
Ember are o abordare diferită a vederilor. De fapt, convenția afirmă că opiniile ar trebui să vorbească direct cu controlorii și nu cu modelele. Aceasta este o bună practică, dacă intenționați să urmați o arhitectură stabilă. Voi explica eșantionul pentru aceeași vizualizare:
var TaskView = Ember.View.extend (templateName: "task-template", mark_as_done: function () / * cod aici * /, update_body: function () / * cod aici * /);
Asta e. Dar unde sunt toate lucrurile de randare? Ei bine, Ember ridică acea boilerplate pentru tine. Pur și simplu spuneți ce este șablonul, controlerul care deține obiectul de date și apoi trebuie doar să îl adăugați la DOM
.
var task_view = TaskView.create (controler: task_controller // Ember.ObjectController); task_view.append ();
Atunci când creați o instanță nouă de vizualizare, aceasta va lega conținutul controlerului (care poate fi un Ember.Object
sau o listă a acestora) la vedere. Când decideți să adăugați vizualizarea la DOM
, acesta va căuta șablonul și va plasa marcajul generat pentru dvs..
Spinele este mai explicit și mai puțin magic.
Spinele este mai explicit și mai puțin magic. Creați a Vedere
, spune-i ce șablon să folosești și cum, să înregistrezi evenimentele și să faci ce trebuie să faci. Ei dețin pagina. Acesta este un început excelent pentru cei care provin dintr-un mediu jQuery. Cu toate acestea, atunci când ceva trebuie actualizat în DOM
, vă veți confrunta cu unele boilerplate.
Cu Ember, actualizările sunt automate. Voi spuneți ce șablon este și că callback-urile sunt funcții în interiorul obiectului de vizualizare. Ori de câte ori un obiect este actualizat, vizualizarea actualizează automat pagina.
Unele legături comune de eveniment sunt construite în Ember, iar altele trebuie introduse în șablon. Este bine pentru cei care vin dintr-o perspectivă de backend, deoarece reduce boilerplate într-un mod considerabil.
Modelele din Backbone și Ember sunt destul de asemănătoare. Ele dețin informații pentru o entitate comercială.
Un exemplu de model Backbone arată astfel:
var TaskModel = Backbone.Model.extend ();
Cu această linie simplă de cod, aveți un model de lucru cu ODIHNĂ
comunicare completă încorporată. Ai metode cum ar fi Salvați
să persiste datele și aduce
să o încărcați gratuit; nu este necesar niciun plugin. Validarea este, de asemenea, construită în modul în care datele sunt salvate prin furnizarea unei valida
callback, care returnează un boolean care spune că înregistrarea trebuie salvată sau nu. Punerea în aplicare a validării este încă pentru dezvoltator de a face.
Pentru a crea o nouă sarcină, instanțiați un nou TaskModel
.
var task = TaskModel nou (body: "Făcând gazonul", done: false);
Puteți injecta atâtea atribute pe care le doriți, deoarece lista de atribute a sarcinii nu este strictă (gândiți-vă la ea ca la scheme,). Încă puteți seta o implicite
proprietate atunci când se extinde Backbone.Model
.
Cu Ember, nu există modele, doar obiecte. Poate arata cam asa:
Var TaskObject = Ember.Object.extend ();
Similar cu versiunea din spate, trebuie să vă extindeți Ember.Object
pentru a crea o clasă de obiecte. Acesta moștenește toate funcționalitățile de bază pentru o clasă cu apeluri de apel atunci când devine schimbat, creat și distrus, printre alte caracteristici. Cu toate acestea, nu are comunicare de backend din cutie. Ember.Data
este în curs de dezvoltare ca o extensie a Ember.Object
de către echipa de bază Ember pentru a îndeplini această nevoie. Este deja utilizabil, dar nu este stabil în măsura în care documentația spune.
Obiectele ember sunt, de asemenea, considerate a fi scheme,. Pentru a injecta valorile implicite în obiecte ember, extindeți Ember.Object
trecând un obiect cu atribute cât mai multe de care aveți nevoie.
var TaskObject = Ember.Object.extend (body: "Mow the grass", terminat: false);
Backbone-ul are o modalitate consolidată de sincronizare cu un strat de persistență ODIHNĂ
și asta este o convenție bună acolo. Este un lucru mai puțin pe care trebuie să-l configurați pentru a lucra cu un server de backend.
Ember se străduiește să facă Ember.Data
gata pentru utilizarea în producție și pare promițătoare. Chiar și așa, particularitatea obiectelor Ember având legături în două direcții face ca moartea să devină ușor de realizat conexiuni între obiecte.
În acest moment în citirea dvs., aveți un punct de inflexiune între stabilitatea Backbone în comunicarea cu serverul backend și legăturile lui Ember. Orice ar fi cel mai important pentru tine ar trebui să determine decizia ta.
Acesta este locul în care cadrele partajează. Ei au un decalaj conceptual enorm cu privire la modul în care să lipiți lucrurile împreună în aplicația dvs. În timp ce Backbone se străduiește să rămână cât mai simplu și mai flexibil posibil, Ember sacrifică mărimea codului pentru o arhitectură mai bună. Este un compromis, într-adevăr.
Avertisment: următoarele exemple nu conțin eșantioane de șabloane HTML.
După cum am remarcat, Backbone își propune simplitatea care se transformă în flexibilitate și atinge astfel de atribute prin intermediul lipsa unei clase de controler. Cea mai mare parte a workhorse este distribuită în jurul vizualizărilor, colecțiilor, modelelor și routerului (dacă alegeți să utilizați Backbone's Router
).
Având în vedere o listă de sarcini care trebuie gestionate, ar fi necesar:
Colectie
pentru a stoca sarcinile.Model
pentru a stoca informația unei sarcini.Vedere
pentru a reprezenta colecția.Vedere
pentru a reprezenta fiecare sarcină.Router
pentru a gestiona adresele URL.Cea mai mare parte a logicii aplicației va trăi în vizualizări, deoarece acestea leagă modele de DOM
. Nu există o distincție clară a responsabilităților, deoarece viziunea face totul. Acesta poate fi bun pentru aplicații mici, care nu necesită o arhitectură solidă.
Pentru a afișa o listă de sarcini, ați ajunge la ceva de genul:
var TaskList = Backbone.Collection.extend (model: Task);
var TaskModel = Backbone.Model.extend ();
var TaskListView = Backbone.View.extend (render: function () this. $ el.empty (); pentru (_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, thismodel.attributes));
var Router = Backbone.Router.extend (initialize: function () this.tasks = noua TaskList; this.view = noua TaskListView (colectia: this.tasks ,, tasks_list: function () this.view.render (); $ (".cache: prima"). html (this.view.el); start: function () Backbone.history.start pushState: true, root: "/ bilete /"););
Observați că colecția nu are un model propriu; mai degrabă, el delegă la o singură vedere de sarcină fiind redat și adăugat la rezultatul final pus pe pagină.
Numărul de clase necesare pentru a avea aceeași setare este puțin mai mare.
Colectie
, ai avea un ArrayController
, care funcționează foarte mult.ObjectController
pentru gestionarea unei singure sarcini. Model
, ai avea un Obiect
/ DS.Model
, care funcționează la fel.Vedere
s.Router
este de asemenea responsabil pentru gestionarea adreselor URL.S-ar putea să vă gândiți că cele două cadre nu sunt prea diferite una de cealaltă. Este destul de tentant, dar nu este chiar adevărat. Unele diferențe deosebite sunt:
DOM
, nu controlerul.Separarea preocupărilor este bună pe termen lung. Controlerul manipulează datele, vizualizările se ocupe de DOM
, perioadă. Acest tip de decuplată și coezivă, fără boilerplateless design permite testare mai concentrată.
Implementarea pentru a afișa aceeași listă de sarcini ar fi ceva asemănător cu cele de mai jos, având în vedere o aplicație completă Ember:
window.App = Ember.Application.create (); App.ApplicationController = Ember.ObjectController.extend (); App.ApplicationView = Ember.View.extend (templateName: "cerere");
App.Task = Ember.Object.extend ();
App.TasksController = Ember.ArrayController.extend (conținut: []);
App.TasksView = Ember.View.extend (templateName: "my-list");
App.Router = Ember.Router.extend (rădăcină: Ember.Route.extend (index: Em.Route.extend (route: '/', connectOutlets: funcția (router) router.get ('applicationController') .connectOutlet ("sarcini");));
În cazul lui Ember, nu se spune prea multe despre cum se fac lucrurile înăuntru. Toate boilerplate-ul este luat, astfel încât să vă puteți concentra asupra a ceea ce contează cu adevărat în aplicația dvs.: definiți un obiect de activitate, un controler al listei de sarcini cu un matrice numit conţinut
, vizualizarea dvs. și ruterul le combină pur și simplu și le pune în pagină.
După ce a realizat cum funcționează Ember, începe să devină eliberator.
În mod previzibil, acest segment a fost cel mai greu de înțeles pentru ambele cadre. Rostul a fost cu siguranță mai ușor de învățat, iar natura sa flexibilă dă controlul asupra modului în care obiectele și obiectele se află DOM
interacționa. Acest lucru ar putea fi bun pentru dvs., dacă într-adevăr aveți nevoie de acest tip de flexibilitate, dar totuși doriți să mențineți o structură pentru logica aplicației dvs. în partea JavaScript.
În ceea ce-l privește pe Ember, implementarea ei uluitoare poate fi înfricoșătoare la început. Cu toate acestea, după ce a realizat cum funcționează Ember, începe să devină eliberator. Toate convențiile setate pentru tine vă eliberează de pe platforma de boot și de configurație, permițându-vă să vă concentrați asupra aplicației. Acest lucru este similar cu ceea ce a făcut Rails pentru dezvoltarea de servere care a atras atenția atât de mult.
Ember a fost menit să ridice povara obișnuită a dezvoltării JavaScript în browser.
Până în prezent, scopul de a arăta cele două instrumente a fost acela de a recunoaște scopul lor unic și nobil: de a delega putere la partea clientului, prin structura și metodă.
Rata de bază a spatelui este cu siguranță abordarea KISS. Acesta vă oferă minimul de a renunța la DOM
ca susținător principal al aplicației dvs. și începeți să utilizați obiecte JavaScript real care pot fi testate și proiectate corespunzător.
Backbone vine cu colecții, modele, vederi și router, printre alte utilități mici. Sunteți liber să faceți ceea ce vă rog cu ei.
Ember, pe de altă parte, a fost construit cu o mentalitate diferită, deoarece vizează o modalitate mult mai convențională și mai avizată de a construi aplicații web. Ea abordează un set de probleme comune, cum ar fi boilerplate, legarea datelor și DOM
templând astfel încât să nu trebuie să vă faceți griji de la început. Ember a fost menit să ridice povara obișnuită a dezvoltării JavaScript în browser.
Ember vine echipat cu obiecte, controlori, vizualizări cu auto-actualizare, mașini de stat, legături, observatori și un router (care este de asemenea o mașină de stat), toate acestea provocând o bună doză de convenții. Aveți o arhitectură deja proiectată și pregătită să începeți să lucrați fără a pierde concentrarea.
Gândiți-vă la diferența de învățare. Experiența și moștenirea dvs. culturală vor dicta cu fermitate cât de repede se alătură clientului. Dacă vă este frică de ce să faceți sau de cine să alegeți, atunci am lovit un nerv de-al tău și asta e bine! Vrei un răspuns bun pe care să alegeți? Ambii.
Dacă nu sunteți sigur că chiar și jQuery face toată magia, începeți să învățați Backbone. Este mai ușor să începeți, iar documentația este ușor de citit și de înțeles. După ce ați terminat, începeți să construiți ceva. Du-te murdar. Verificați aceste tutoriale dacă aveți nevoie de ajutor.
Dacă sunteți încă în întuneric, citiți articolele lui Yehuda Katz despre cum funcționează JavaScript.
Odată ce veți obține o viziune mai bună asupra modului în care JavaScript funcționează ca o limbă, veți începe să înțelegeți mai bine modul în care obiectele interacționează unul cu celălalt. Când o faci, du-te la Ember. Este mai complicat la început, dar nu renunță. Începeți să citiți documentele și ghidurile. S-ar putea să doriți să verificați intrarea în blog a lui Trek Glowacki chiar înainte de a vă pune mâinile murdare.
Personal, mă înclin spre Ember; Îmi place robustețea la o scară macro, și prefer, de asemenea, convențiile sale. Backbone este un instrument mai ușor de utilizat și mai ușor pentru aplicații mai mici sau caracteristici mici în interiorul unei aplicații existente.
Învăț în continuare atât, cât și câteva provocări:
Care sunt gândurile tale în acest dezastru întreg? Aveți vreo provocare în minte? Orice dificultăți sau obstacole? Să-mi dai de veste!