Intoeren in Ember.js deel 5

Noot van de redactie: het Ember.js-team is overgeschakeld naar een versneld releaseschema en vanaf deze publicatiedatum is dit op versie 1.2.0. Deze zelfstudie is geschreven vóór versie 1.0, maar veel van de concepten zijn nog steeds van toepassing. We doen ons best om tijdig inhoud te verstrekken en deze situaties kunnen van tijd tot tijd plaatsvinden. We zullen werken om dit in de toekomst bij te werken.

In deel 3 van mijn Ember-serie heb ik je laten zien hoe je kunt omgaan met gegevens met behulp van Ember's Ember.Object main base class om objecten te maken die de methoden en eigenschappen definiëren die fungeren als een verpakking voor uw gegevens. Hier is een voorbeeld:

App.Item = Ember.Object.extend (); App.Item.reopenClass (all: function () return $ .getJSON ('http://api.ihackernews.com/page?format=jsonp&callback=?') .Then (function (response) var items = [ ]; response.items.forEach (functie (item) items.push (App.Item.create (item));); return items;);

In deze code, subklasse Ember.Object de ... gebruiken "uitbreiden()"en maak een door de gebruiker gedefinieerde methode genaamd" genaamdallemaal()"dat een verzoek doet aan Hacker News voor JSON-geformatteerde resultaten van zijn nieuwsfeed.

Hoewel deze methode absoluut werkt en zelfs wordt gepromoot door de op taal gebaseerde verhandeling als hun manier om dit te doen, vereist het dat wel u vult u de API in waar u naar wilt verwijzen en geeft deze weer. De meeste MVC-frameworks bevatten meestal ORM-achtige mogelijkheden, dus als u bijvoorbeeld gewend bent aan Rails, bent u goed bekend met de voordelen van ActiveRecord, die helpt bij het beheren en uitvoeren van zware interacties met gegevens.

Het Ember-team wilde hetzelfde doen, maar hun hoofddoel was om eerst een stabiele v1-release van hun core-framework uit te brengen om ervoor te zorgen dat aanvullende componenten op een stabiele basis kunnen worden gebouwd. Ik juich dit eigenlijk toe en ik heb zelfs vermeld dat je dit vanwege het gebruik van de gegevens van Ember moet uitstellen.

Nu Ember RC8 uit is en v1 om de hoek lijkt te komen, vond ik het een goed moment om te beginnen met het verkennen van Ember Data en te zien wat het biedt.

Ember Data

Het eerste wat ik wil benadrukken is dat Ember Data een werk in uitvoering is en op dezelfde manier als dat van Ember de komende maanden waarschijnlijk een aantal verbroken API-wijzigingen zal zien. Hoewel dat niet ideaal is, is het belangrijk om te beginnen met kijken naar hoe u uw apps zou structureren met behulp van de bibliotheek. Om je een goede beschrijving te geven van wat Ember Data biedt, heb ik gekopieerd in de goed geschreven beschrijving van de GitHub-pagina:

Ember Data is een bibliotheek voor het laden van gegevens van een persistentielaag (zoals een JSON API), deze gegevens toewijzen aan een reeks modellen in uw clienttoepassing, die modellen bijwerken en de wijzigingen vervolgens opslaan in een persistentielaag. Het biedt veel van de faciliteiten die je zou vinden in server-side ORM's zoals ActiveRecord, maar is specifiek ontworpen voor de unieke omgeving van JavaScript in de browser.

Dus zoals ik al zei, het is bedoeld om veel van de complexiteit van het werken met data te abstraheren.

Het gebruik van Ember-gegevens

Als u mijn vorige zelfstudies hebt gelezen, moet u goed bekend zijn met het instellen van een pagina om gebruik te maken van Ember. Als je dit nog niet hebt gedaan, ga dan naar de startpagina van Ember.js en pak de Starter Kit. Je kunt het midden op de pagina vinden zoals het wordt weergegeven via een grote knop. Dit geeft je de meest recente versie van Ember die je nodig hebt om met Ember Data te werken. De eenvoudigste manier om een ​​downloadbare versie van Ember Data te krijgen, is door naar de API-documenten te gaan modellen, scrol naar beneden en download de bibliotheek. Bovendien kunt u naar de bouwt pagina om de nieuwste builds van een aan Ember gerelateerde bibliotheek op te halen.

Het toevoegen van Ember Data is zo simpel als het toevoegen van een ander JavaScript-bestand aan de mix, zoals dit:

     

Dit geeft u nu toegang tot de objecten, methode en eigenschappen van Ember Data.

Zonder configuratie kan Ember Data records en relaties laden en opslaan die worden geserveerd via een RESTful JSON API, op voorwaarde dat deze bepaalde conventies volgt.

Een winkel definiëren

Ember gebruikt een speciaal object genaamd a op te slaan om modellen te laden en gegevens op te halen en is gebaseerd op de Sintel DS.Store klasse. Dit is hoe je een nieuwe winkel zou definiëren:

App.Store = DS.Store.extend (...);

Als je het me herinnert van mijn vorige artikelen, "App" is slechts een naamruimte die is gemaakt voor de toepassingsniveau-objecten, -methoden en -eigenschappen voor de toepassing. Hoewel het geen gereserveerde term is in Ember, zou ik je willen aanmoedigen om dezelfde naam te gebruiken als bijna elke tutorial en demo die ik heb gezien gebruikt het voor consistentie.

De winkel die u maakt, houdt de modellen vast die u maakt en fungeert als de interface met de server die u in uw adapter definieert. Standaard maakt en associeert Ember Data met uw winkel een REST-adapter op basis van de DS.RestAdapter klasse. Als u eenvoudig de bovenstaande code hebt gedefinieerd, heeft u standaard een adapter gekoppeld. Ember-magie op zijn best. U kunt ook een fixture-adapter gebruiken als u werkt met in-memory-gebaseerde gegevens (bijvoorbeeld JSON die u laadt vanaf de code) maar aangezien dit gaat over het maken van API-aanroepen, is de REST-adapter meer geschikt.

U kunt ook uw eigen adapter definiëren voor situaties waarin u meer aangepaste controle nodig hebt over interfacing met een server met behulp van de adapter eigendom in uw winkelverklaring:

App.Store = DS.Store.extend (adapter: 'App.MyCustomAdapter');

Modellen definiëren

De code die ik bovenaan deze zelfstudie heb vermeld, was een voorbeeld van hoe te gebruiken Ember.Object om de modellen voor uw toepassing te maken. Dingen veranderen een beetje wanneer je modellen definieert via Ember Data. Ember Data biedt een ander object genaamd DS.Model die u subklasse voor elk model dat u wilt maken. Neem bijvoorbeeld de code van hierboven:

App.Item = Ember.Object.extend ();

Het ziet er nu als volgt uit:

App.Item = DS.Model.Extend ()

Niet echt een verschil qua uiterlijk, maar een groot verschil in functionaliteit, omdat je nu toegang hebt tot de mogelijkheden van de REST-adapter en de ingebouwde relaties van Ember Data zoals één-op-één, één-op-veel en meer. Het belangrijkste voordeel is echter dat Ember Data de haken biedt voor de interactie met uw gegevens via uw modellen, in plaats van dat u uw eigen gegevens moet rollen. Opnieuw verwijzen naar de code van boven:

App.Item.reopenClass (all: function () return $ .getJSON ('http://api.ihackernews.com/page?format=jsonp&callback=?') .Then (function (response) var items = [ ];

response.items.forEach (functie (item) items.push (App.Item.create (item));); items terugbrengen; );

Hoewel ik mijn eigen methode moest maken om alle resultaten van mijn JSON-aanroep te retourneren, biedt Ember Data een vind() methode die precies dit doet en ook dient om de resultaten te filteren. Dus alles wat ik moet doen is de volgende oproep doen om al mijn gegevens terug te sturen:

App.Item.find ();

De vind() methode stuurt een Ajax-verzoek naar de URL.

Dit is precies wat zoveel ontwikkelaars naar Sintel trekt; de vooruitziende blik om dingen gemakkelijker te maken.

Een ding om in gedachten te houden is dat het belangrijk is om in het model de kenmerken te definiëren die u later wilt gebruiken (bijvoorbeeld in uw sjablonen). Dit is eenvoudig te doen:

App.Post = DS.Model.extend (title: DS.attr ('string'));

In mijn demo-app wil ik de eigenschap title gebruiken die is geretourneerd via JSON, dus met de attr () methode, specificeer welke attributen een model tot mijn beschikking heeft.

Een ding dat ik wil vermelden, is dat het om gegevens gaat ongelooflijk kieskeurig over de structuur van de geretourneerde JSON. Omdat Ember gebruikmaakt van directorystructuren voor het identificeren van specifieke delen van uw applicaties (onthoud de naamconventies die we in mijn eerste Ember-artikel hebben besproken?), Maakt het bepaalde veronderstellingen over de manier waarop de JSON-gegevens zijn gestructureerd. Het vereist dat er een benoemde root is die zal worden gebruikt om de terug te zenden data te identificeren. Dit is wat ik bedoel:

'posts': ['id': 1, 'title': 'Een vriend van mij heeft dit net gepost.', 'url': 'http://i.imgur.com/9pw20NY.jpg'] [js] 

Als je het zo had gedefinieerd:

[js] 'id': '1', 'title': 'Een vriend van mij heeft dit net gepost.', 'url': 'http://i.imgur.com/9pw20NY.jpg', 'id': '2', 'title': 'Een vriend van mij heeft dit net gepost.', 'url': 'http://i.imgur.com/9pw20NY.jpg',

Ember Data zou volledig hebben gestaakt en de volgende fout hebben gegenereerd:

Uw server heeft een hash met de sleutel-ID geretourneerd, maar u hebt er geen toewijzing voor.

De reden is dat het model wordt genoemd "App.Post", Ember Data verwacht een URL te vinden met de naam "posts" waaruit deze de gegevens zal halen. Dus als ik mijn winkel als zodanig definieerde:

App.Store = DS.Store.extend (url: 'http: //emberdata.local');

en mijn model als volgt:

App.Post = DS.Model.extend (title: DS.attr ('string'));

Ember Data zou aannemen dat het Ajax-verzoek van de vind() methode zou er als volgt uitzien:

http: //emberdata.local/posts

En als u een verzoek indient voor een specifieke ID (zoals find (12)), ziet het er als volgt uit:

http: //emberdata.local/posts/12

Deze kwestie heeft me gemeen gemaakt, maar bij een zoekopdracht zijn er veel discussies over gevonden. Als u uw JSON-resultaten niet op deze manier kunt instellen, moet u een aangepaste adapter maken om de resultaten te masseren om ze correct te serialiseren voordat u ze kunt gebruiken. Ik bedwing dit hier niet, maar ben van plan daar binnenkort meer van te ontdekken.

De demo-app

Ik wilde deze tutorial met opzet eenvoudig houden, omdat ik weet dat Ember Data aan het veranderen is en ik wilde een kort overzicht geven van wat het opleverde. Daarom heb ik een snelle demo-app gemaakt met behulp van Ember Data om JSON-gegevens van mijn eigen lokale server te halen. Laten we naar de code kijken.

Eerst maak ik mijn toepassingsnaamruimte (die je zou doen voor elke Ember-app):

// Maak onze applicatie App = Ember.Application.create ();

Vervolgens definieer ik mijn gegevensopslag en verklaar ik de url van waaruit het model de gegevens zal ophalen:

App.Store = DS.Store.extend (url: 'http: //emberdata.local';);

In het model specificeer ik het attribuut: titel, welke ik later in mijn sjabloon zal gebruiken:

// Ons model App.Post = DS.Model.extend (title: DS.attr ('string'));

Ten slotte koppel ik het model aan de route via de haak van het model. Merk op dat ik de voorgedefinieerde Ember Data-methode gebruik vind() om onmiddellijk mijn JSON-gegevens terug te trekken zodra de app is gestart:

// Onze standaardroute. App.IndexRoute = Ember.Route.extend (model: function () return App.Post.find (););

In de sjabloon voor de hoofdpagina (index) gebruik ik de #elk Stuurrichtlijn om de resultaten van mijn JSON-gegevens te bekijken en de titel van elk van mijn berichten weer te geven:

 

Dat is het! Geen Ajax-oproep om te maken of speciale methoden om met mijn gegevens te werken. Ember Data zorgde voor het bellen en opslaan van de XHR-gegevens.

Vin

Dit is ongelooflijk simplistisch en ik wil je niet laten geloven dat het allemaal eenhoorns en puppyhonden zijn. Toen ik door het proces van werken met Ember Data ging, merkte ik dat ik terug wilde gaan naar het gebruik Ember.Object waar ik meer controle had. Maar ik realiseer me ook dat er veel werk aan de winkel is om de gegevens van Ember te verbeteren, vooral als het gaat om het beheren van diverse gegevensresultaten. Het is dus belangrijk om op zijn minst een kickstart te geven aan het proces van begrijpen hoe dit ding werkt en zelfs constructieve feedback te bieden aan het team.

Dus ik dring er bij je op aan om er in te springen en ermee te beginnen sleutelen, vooral die met een erg sterke ORM-achtergrond en kunnen helpen de richting van Sintel Data te bepalen. Dit is de beste tijd om dat te doen.