Dus je hebt de uitdaging aangenomen om dik te worden aan de client-kant; goed gedaan. U hebt alle raamwerken bekeken en weet niet zeker welke u moet kiezen? Je bent niet alleen. Lees verder.
Mijn ervaring, bij het leren van de manier om client-side apps te schrijven, blijkt te zijn stijl en hard. Het is niet gemakkelijk om bewust te kiezen voor gebruik MV *
op de client voor iemand die JavaScript heeft geschreven, volledig gebaseerd op jQuery en zijn plug-ins. Dit is een geheel nieuw paradigma; het vereist basisvaardigheden voor programmeren en een aanzienlijke kennis van het ontwerp van JavaScript (de taal). Als je ervaring betrekking heeft op de mijne, lees dan verder!
Ik zal de belangrijkste verschillen tussen twee van de meest populaire JavaScript-clientframe-frameworks uitleggen: Backbone.js en Ember.js. Elk van deze tools heeft sterke punten, evenals zwakke punten die u kunnen helpen een meer doordachte keuze te maken.
Disclaimer: als softwareprofessionals moeten we omgaan met diversiteit van meningen. Backbone en Ember zijn resultaten van eigenzinnige en ervaren professionals, zoals jij en ik. Het ene hulpmiddel is niet beter dan het andere; ze dienen gewoon verschillende mensenmassa's en lossen verschillende problemen op. Bedankt Trek voor het gedegen advies.
Backbone is veel gemakkelijker te leren dan Sintel.
Eerst en vooral moet je begrijpen dat Backbone en Ember met name een iets andere drukte dienen. Wat de complexiteit betreft, is Backbone veel gemakkelijker te leren dan Sintel. Er wordt echter wel gezegd dat wanneer je eenmaal de leerling bent, het nauwelijks ingewikkelder wordt. Neem Trek's woord erop. Als je net begint met wat echt JavaScript, dan is Backbone misschien je tool. Als je echter weet dat je veel meer dan alleen een paar eenvoudige use-cases te verwerken hebt, zou je misschien een voorkeur hebben voor Ember.
Jeremy Ashkenas heeft Backbone gebouwd, dus het zou mogelijk zijn om haal de waarheid uit de DOM
. Wat hij hiermee bedoelt, is: wat je ook deed met alleen jQuery / Mootools / Prototype kon en zou beter moeten worden geëxtraheerd in pure JavaScript-structuren - objecten, als je wilt. In plaats van gebruiken DOM
elementen om uw zakelijke elementen en gedrag te definiëren, Backbone nodigt u uit om het andersom te doen. JavaScript-objecten zijn de kern en de DOM
is slechts een weergave van die gegevens.
Met Backbone heeft u een aantal beweringen:
DOM
U krijgt volledige controle over de manier waarop u uw app bouwt. Backbone was bedoeld om u een eenvoudige manier te geven om uw modelobjecten te ontwerpen en hoe deze met elkaar omgaan via eventbindingen.
rendering HTML
naar de DOM
is van je verantwoordelijkheid. U bent vrij om elke sjabloon-engine te kiezen: Moustache, DoT, Handlebars, Underscore, etc. Backbone bevat a Uitzicht
prototype dat de verantwoordelijkheid heeft van het articuleren van de DOM
en uw JavaScript-kern.
Toen Tilde begon met het bouwen van Ember, deed het dit met een veel uitdagender doel: naar bieden standaardconventies in client-side ontwikkeling, elimineren zo veel boilerplate als mogelijk. Het resultaat is een veel ambitieuzer kader dat streeft naar een voorspelbare architectuur en gestage ontwikkeling.
Ember deelt enkele gemeenschappelijke punten met Backbone in de manier waarop het probeert gegevens en gedrag uit de DOM
door uitbreidbare JavaScript-prototypen te bieden, maar dit gebeurt op een heel andere manier dan Backbone.
Sintel staat op:
Zowel Backbone als Ember hebben veel voorkomende kernbegrippen, zoals keer bekeken. Ze vertegenwoordigen allebei DOM
communicatie, respectievelijk. De manier waarop ze dit concept uitvoeren, is echter iets anders.
Ik gebruik de Todo-use-case voor de onderstaande voorbeelden, geïnspireerd op de TodoMVC-showcase.
Een Backbone View kan zoiets als dit:
var TaskView = Backbone.View.extend (tagName: "li", sjabloon: "task-template", render: function () // uw code om hier weer te geven., events: "click .mark-done" : "mark_as_done", "change .body": "update_body", mark_as_done: function () / * code hier * /, update_body: function () / * code hier * /);
Dit is gewoon de definitie van uw mening. U moet er een instantiëren als u wilt dat deze op de pagina staat. Zoiets zal het lukken:
var task_view = nieuwe taak (model: task_model); . $ ( "Body") toevoegen (task_view.el);
U ziet dat we een model doorgeven, zodat u een verwijzing kunt houden naar het gegevensobject dat de sjabloon invult. De sjabloon
eigenschap in de weergave kan worden gebruikt om een externe sjabloon te bellen, via een ID. Ik heb zoiets in het verleden gebruikt:
var TaskView = Backbone.View.extend (template: "# task-template", render: function () this. $ el.html (Moustache.render ($ (this.template) .html ()), dit. model); // snip);
Ember heeft een andere kijk op meningen. In de conventie wordt zelfs gezegd dat views rechtstreeks met controllers en niet met modellen moeten praten. Dit is een goede gewoonte als u van plan bent om een stabiele architectuur te volgen. Ik zal het voorbeeld voor dezelfde weergave uitleggen:
var TaskView = Ember.View.extend (templateName: "task-template", mark_as_done: function () / * code hier * /, update_body: function () / * code hier * /);
Dat is het. Maar waar zijn al het renderingmateriaal? Wel, Sintel tilt die boilerplate voor je op. Zeg eenvoudig wat de sjabloon is, de controller die het gegevensobject bevat en voeg deze toe aan de DOM
.
var task_view = TaskView.create (controller: task_controller // Ember.ObjectController); task_view.append ();
Wanneer u een nieuwe weergave-instantie maakt, wordt de inhoud van de controller gekoppeld (dit kan een Ember.Object
of een lijst ervan) in de weergave. Wanneer u besluit de weergave toe te voegen aan de DOM
, het zal de sjabloon opzoeken en de gegenereerde markup voor u plaatsen.
Backbone is meer expliciet en minder magisch.
Backbone is meer expliciet en minder magisch. Je maakt een Uitzicht
, vertel het welke sjabloon je moet gebruiken en hoe, registreer de evenementen en doe wat je moet doen. Zij bezitten de pagina. Dat is een goed begin voor diegenen die een jQuery-achtergrond hebben. Wanneer iets echter moet worden bijgewerkt in de DOM
, je zult tegen een boilerplate staan.
Met Ember worden updates automatisch uitgevoerd. U zegt welke sjabloon het is en event-callbacks zijn functies binnen het view-object. Elke keer dat een object wordt bijgewerkt, wordt de pagina automatisch bijgewerkt in de weergave.
Sommige algemene gebeurtenisbindingen zijn ingebouwd in Sintel en andere moeten in de sjabloon worden geplaatst. Het is goed voor degenen die vanuit een back-end perspectief komen, omdat het boilerplate op een aanzienlijke manier vermindert.
Modellen in Backbone en Ember lijken veel op elkaar. Ze bevatten informatie voor een zakelijke entiteit.
Een voorbeeld van een Backbone-model ziet er als volgt uit:
var TaskModel = Backbone.Model.extend ();
Met deze eenvoudige regel code heeft u een werkmodel met RUST UIT
volledige communicatie ingebouwd. Je krijgt methoden zoals opslaan
om de gegevens en halen
om het gratis te laden; er is geen plug-in vereist. Validatie is ook ingebouwd in de manier waarop gegevens worden opgeslagen door een bevestigen
callback, die een boolean retourneert die aangeeft dat de record moet worden opgeslagen of niet. De implementatie van de validatie is nog steeds voor de ontwikkelaar.
Als u een nieuwe taak wilt maken, maakt u een nieuwe taak TaskModel
.
var task = new TaskModel (body: "Mow the lawn", done: false);
Je mag zoveel attributen injecteren als je wilt, omdat de attributenlijst van de taak niet strikt is (denk eraan als schemaless). U kunt nog steeds een instellen defaults
eigendom bij verlenging Backbone.Model
.
Met Ember zijn er geen modellen, alleen objecten. Het ziet er ongeveer zo uit:
var TaskObject = Ember.Object.extend ();
Net als bij Backbone, moet je uitbreiden van Ember.Object
om een objectklasse te maken. Het neemt alle basisfuncties over van een klasse met callbacks voor wanneer deze wordt gewijzigd, gemaakt en vernietigd, naast andere functies. Het heeft echter geen back-endcommunicatie uit de doos. Ember.Data
wordt ontwikkeld als een uitbreiding van Ember.Object
door het kernteam van Ember om aan die behoefte te voldoen. Het is al bruikbaar, maar niet stabiel voor zover de documentatie het zegt.
Voorwerpen uit de Sintel worden ook beschouwd als te zijn schemaless. Om standaardwaarden in Sintel-objecten te injecteren, verleng je Ember.Object
door een object met zoveel attributen door te geven als u wenst.
var TaskObject = Ember.Object.extend (body: "maai het gazon", done: false);
Backbone heeft een geconsolideerde manier om te synchroniseren met een persistentielaag RUST UIT
en dat is een goede afspraak daar. Het is een ding minder dat u hoeft te configureren om met een backend-server te werken.
Sintel werkt zijn weg naar het maken Ember.Data
klaar voor productie gebruik, en het ziet er veelbelovend uit. Desalniettemin maakt de bijzonderheid van voorwerpen uit de Sintel met tweewegsbindingen het gemakkelijk om verbindingen tussen objecten uit te voeren.
Op dit punt in uw meting heeft u een omslagpunt tussen de stabiliteit van Backbone in de communicatie met de backend-server en de bindingen van Ember. Wat het meest belangrijk voor u is, moet uw beslissing bepalen.
Dit is waar de kaders uit elkaar gaan. Ze hebben een enorme conceptuele kloof over hoe je dingen in je app moet lijmen. Terwijl Backbone ernaar streeft zo eenvoudig en flexibel mogelijk te blijven, offert Ember de codebase-omvang op voor een betere architectuur. Het is echt een afweging.
Waarschuwing: de volgende voorbeelden bevatten geen voorbeelden van HTML-sjablonen.
Zoals ik al zei, streeft Backbone naar eenvoud die zich omzet in flexibiliteit en deze eigenschappen bereikt precies door het ontbreken van een controllerklasse. Het grootste deel van het werkpaard is verdeeld over views, collecties, modellen en de router (moet u ervoor kiezen om Backbone's te gebruiken router
).
Gezien een lijst met taken die moeten worden beheerd, zou het vereisen:
Verzameling
om de taken op te slaan.Model
om de informatie van een taak op te slaan.Uitzicht
om de verzameling te vertegenwoordigen.Uitzicht
om elke taak te vertegenwoordigen.router
om URL's te beheren.Het grootste deel van de applicatielogica zal in de views leven, omdat ze modellen verbinden met de DOM
. Er is geen duidelijk onderscheid tussen verantwoordelijkheden, omdat het beeld alles doet. Het kan goed zijn voor kleine toepassingen waarvoor geen solide architectuur vereist is.
Om een lijst met taken weer te geven, zou je zoiets als dit krijgen:
var TaskList = Backbone.Collection.extend (model: Task);
var TaskModel = Backbone.Model.extend ();
var TaskListView = Backbone.View.extend (render: 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)); retourneer dit;);
var Router = Backbone.Router.extend (initialize: function () this.tasks = nieuwe TaskList; this.view = nieuwe 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: "/ tickets /"););
Merk op dat de verzameling geen eigen sjabloon heeft; in plaats daarvan delegeert het naar een enkele taakweergave die wordt weergegeven en toegevoegd aan het uiteindelijke resultaat dat op de pagina wordt geplaatst.
Het aantal klassen dat vereist is om dezelfde setup te hebben is iets groter.
Verzameling
, je zou een hebben ArrayController
, die heel veel op elkaar lijken.ObjectController
voor het beheren van een enkele taak. Model
, je zou een hebben Voorwerp
/ DS.Model
, die hetzelfde werken.Uitzicht
s.router
is ook verantwoordelijk voor het beheer van URL's.Je denkt misschien dat de twee frameworks niet te veel van elkaar verschillen. Het is nogal verleidelijk, maar het is niet helemaal waar. Enkele bijzondere verschillen zijn:
DOM
, niet de controller.De scheiding van zorgen is goed op de lange termijn. Controller verwerkt gegevens, views verwerken de DOM
, periode. Dit soort ontkoppeld en samenhangend, ketelvrij ontwerp maakt een meer gerichte testbaarheid mogelijk.
De implementatie om dezelfde lijst met taken weer te geven zou ongeveer het volgende zijn, gezien een volledige Ember-applicatie:
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');));
In het geval van Ember wordt er niet veel gezegd over hoe dingen binnen worden gedaan. Al dat overzicht is weggenomen, zodat je je kunt concentreren op wat echt belangrijk is in je app: je definieert een taakobject, een takenlijstcontroller met een array genaamd inhoud
, jouw mening en de router combineert ze eenvoudigweg allemaal en plaatst het op de pagina.
Nadat het zich heeft gerealiseerd hoe Ember echt werkt, begint het bevrijdend te worden.
Het is te verwachten dat dit segment het moeilijkst te begrijpen was voor beide raamwerken. Backbone was beslist gemakkelijker om te leren en zijn flexibele karakter geeft controle over de manier waarop objecten en DOM
interageren. Dit kan goed voor u zijn, als u echt die flexibiliteit nodig hebt maar toch een structuur wilt behouden voor de logica van uw app in JavaScript.
Wat betreft Ember, zijn adembenemende implementatie kan in het begin eng zijn. Maar nadat het zich heeft gerealiseerd hoe Ember echt werkt, begint het bevrijdend te worden. Alle conventies die het raamwerk voor u instelt, ontheft u van boilerplate en configuratie, zodat u zich op uw app kunt concentreren. Dit is vergelijkbaar met wat Rails deed voor de ontwikkeling van serverside die zoveel aandacht trok.
Ember was bedoeld om de gemeenschappelijke last van JavaScript-ontwikkeling in de browser op te heffen.
Tot nu toe is het hele punt van het tonen van de twee gereedschappen geweest om hun enige en nobele doel te erkennen: delegeren macht aan de client-kant, door zowel structuur en methode.
Backbone kernsterkte is absoluut de KISS-aanpak. Het biedt je het minimum om het te laten gaan DOM
als de belangrijkste supporter van uw app en begin met het gebruik van echte JavaScript-objecten die op de juiste manier kunnen worden getest en ontworpen.
Backbone zit boordevol collecties, modellen, views en de router, naast andere kleine hulpprogramma's. Je bent vrij om te doen wat je wilt.
Ember daarentegen is gebouwd met een andere mindset, omdat het streeft naar een veel conventionelere en meer eigenzinnige manier om webapps te bouwen. Het pakt een aantal veel voorkomende problemen aan, zoals boilerplate, data binding en DOM
sjabloneren, zodat je er vanaf het begin geen zorgen over hoeft te maken. Ember was bedoeld om de gemeenschappelijke last van JavaScript-ontwikkeling in de browser op te heffen.
Ember zit boordevol objecten, controllers, automatisch bijgewerkte views, state-machines, bindingen, waarnemers en een router (die ook een state-machine is), allemaal opgeroepen met een goede dosis conventies. Je hebt een architectuur die al is ontworpen en klaar is om te werken zonder de focus te verliezen.
Let op de leemte. Je ervaring en cultureel erfgoed zullen sterk bepalen hoe snel je je bij de klant voegt. Als je bang bent van wat te doen of welke je moet kiezen, dan heb ik een lef voor je geslagen en dat is goed! Wil je een goed antwoord kiezen? Beide.
Als je niet zeker weet hoe zelfs jQuery al zijn magie doet, begin dan met het leren van Backbone. Het is gemakkelijker om te beginnen en de documentatie is doodeenvoudig om te lezen en te begrijpen. Nadat je klaar bent, begin je iets te bouwen. Ga vies. Raadpleeg deze tutorials als u hulp nodig heeft.
Als je nog steeds in het donker bent, lees dan Yehuda Katz's gegevens over hoe JavaScript werkt.
Zodra u een beter beeld krijgt van hoe JavaScript werkt als een taal, krijgt u meer grip hoe de objecten met elkaar omgaan. Als je dat doet, ga je voor Ember. In het begin is het ingewikkelder, maar geef niet op. Begin met het lezen van de documenten en de handleidingen. Je kunt het blogbericht van Trek Glowacki bekijken voordat je je handen vies maakt.
Persoonlijk leun ik naar Ember; Ik geniet van de robuustheid op macro-schaal, en ik geef ook de voorkeur aan conventies. Backbone is een eenvoudiger en gemakkelijker hulpmiddel voor kleinere apps of kleine functies in een bestaande app.
Ik ben nog steeds allebei aan het leren en heb een paar uitdagingen om aan te pakken:
Wat zijn uw gedachten over dit hele debacle? Heb je uitdagingen in gedachten? Eventuele moeilijkheden of belemmeringen? Laat het me weten!