I min innledende artikkel gikk jeg over det grunnleggende i Ember.js-rammen, og grunnleggende begreper for å bygge en Ember-applikasjon. I denne oppfølgingsartikkelen vil vi dykke dypere inn i bestemte områder av rammen for å forstå hvor mange av funksjonene som jobber sammen for å abstrahere kompleksiteten til enkeltsidig applikasjonsutvikling.
Jeg bemerket tidligere at den enkleste måten å få de filene du trenger, er å gå til Ember.js Github repo og dra ned startpakken, og det gjelder fortsatt. Dette boilerplate-settet inneholder alle filene du trenger for å starte din Ember-opplevelse, så vær sikker på å laste den ned fra denne artikkelen.
Det interessante er at startpakken er også et godt eksempel på en veldig grunnleggende Ember-app. La oss gå gjennom det for å få en forståelse av hva som skjer. Legg merke til at jeg skal grave dypere inn i bestemte områder senere, så vær ikke bekymret hvis noe ikke gir umiddelbar forstand i denne delen. Det er mer å gi deg et høyt nivå forståelse av funksjonaliteten før du drar inn i detaljene.
Åpen index.html
i nettleseren din, og du ser følgende:
Velkommen til Ember.js
Dette er ikke veldig spennende, vet jeg, men hvis du ser på koden som gjengitt dette, vil du se at det var gjort med svært liten innsats. Hvis vi ser på "js / app.js", ser vi følgende kode:
App = Ember.Application.create (); App.IndexRoute = Ember.Route.extend (setupController: funksjon (controller) controller.set ('content', ['rød', 'gul', 'blå']););
På sitt mest grunnleggende nivå trenger en Ember-app bare denne linjen til teknisk å betrakte som en "app":
App = Ember.Application.create ();
Denne koden setter opp en forekomst av Ember-applikasjonsobjektet, sammen med en standard programmal, hendelseslyttere og programruter. Ta et øyeblikk og prøv å tenke på koden du normalt må skrive for å opprette et globalt navneområde, en klientside-mal, binde hendelseshåndterer for global brukerinteraksjon og inkludere historie og statlig ledelse i koden din. Ja, den ene linjen gjør alt dette. La oss være klare, skjønt: Jeg sier ikke at det gjør alt arbeidet for deg, men det skaper grunnlaget du vil bygge på, via en metodeanrop.
Det neste settet med kode angir oppførselen til en rute, i dette tilfellet for hovedmenyen index.html
side:
App.IndexRoute = Ember.Route.extend (setupController: funksjon (controller) controller.set ('content', ['rød', 'gul', 'blå']););
Husk at ruter brukes til å administrere ressursene knyttet til en bestemt nettadresse i programmet, og tillater Ember å spore de ulike tilstandene til de enkelte sidene. Nettadressen er nøkkelidentifikatoren som Ember bruker for å forstå hvilken applikasjonsstatus som skal presenteres for brukeren.
I dette tilfellet opprettes ruten ruten som standard i Ember. Jeg kunne også ha uttrykkelig definert ruten på denne måten:
App.Router.map (funksjon () this.resource ('index', path: '/'); // Tar oss til "/");
Men Ember tar seg av det for meg for "roten" av søknaden min. Vi vil takle ruter mer detaljert senere.
Tilbake til følgende kode:
App.IndexRoute = Ember.Route.extend (setupController: funksjon (controller) controller.set ('content', ['rød', 'gul', 'blå']););
I dette tilfellet, når en bruker treffer nettstedets rot, vil Ember sette opp en kontroller som vil laste et utvalg av data med et semantisk navn, kalt innhold
. Disse dataene kan senere brukes i appen, via denne kontrolleren ved hjelp av det navnet. Og det er spesielt hva som skjer i index.html
. Åpne filen og du finner følgende:
Dette er en Handlebars-klientside-mal. Husk at Handlebars er templeringsbiblioteket for Ember, og er viktig for å skape data-drevne brukergrensesnitt for appen din. Ember bruker dataattributter for å koble disse malene til kontrollerne som administrerer dataene dine, enten de er angitt via en rute eller som en frittstående kontroller.
I min siste artikkel nevnte jeg at navnekonvensjoner er viktige i Ember, og at de gjør det enkelt å koble til sammenhengende funksjoner. Hvis du ser på malekoden, ser du at navnet på malen (spesifisert via data-mal-navn attributt) er "indeks". Dette er målrettet og er ment å gjøre det enkelt å koble til kontrolleren som er angitt i ruten med samme navn. Hvis vi ser på rutekoden igjen, ser du at den kalles "IndexRoute" og inne i det er en kontroller med data som er satt:
App.IndexRoute = Ember.Route.extend (setupController: funksjon (controller) controller.set ('content', ['rød', 'gul', 'blå']););
Kontrolleren setter en datakilde med navnet "innhold" og laster det med en rekke strenger for fargene. I utgangspunktet er arrayet din modell, og kontrolleren brukes til å avsløre atributtene til modellen.
Navngivningskonvensjonene tillater Ember å knytte denne rutenes ressurser (for eksempel: kontrolleren med data) til malen spesifisert med samme navn. Dette gir malen tilgang til dataene som er utsatt av kontrolleren, slik at den kan gjøre det ved hjelp av håndteringsdirektiver. Derfra løpes elementene i matrisen over ved hjelp av Handlebars ' Hver direktiv og angi aliaset modell som peker på datakilden:
#each element i modell
For å være mer presis, blir dataene fylt inn i dynamisk opprettede listeposter, og dermed genererer markeringen for deg på fluen. Det er skjønnheten av klientsiden maler.
Jeg tror denne grunnleggende appen fremhever hvordan Ember trekker ut mange ting for deg. Det er litt svart magi skjønt, og det er ikke alltid lett å forstå hvordan ting fungerer. Det skjedde faktisk med meg og ting klarte ikke helt i begynnelsen. Når du begynner å forstå forholdet mellom de ulike komponentene i rammen, begynner det å gjøre mer fornuftig. La oss starte fra grunnen for å få en bedre forståelse av dette.
Jeg berørte kort Ember-applikasjonsobjektet og det faktum at det bygger grunnlaget for søknaden din. The Ember guider gjør en utmerket jobb med å skissere spesifikt hva instantiating en Ember applikasjonsobjekt gjør:
App.PostsView
og App.PostsController
). Dette bidrar til å forhindre forurensing av det globale omfanget. Så denne enkle utsagnet:
App = Ember.Application.create ();
danner opp en hel rekke grunnleggende brikker som din søknad vil avhenge av. Det er viktig å merke seg det app er ikke et nøkkelord i Ember. Det er en vanlig global variabel som du bruker til å definere navneområdet og kan være et gyldig variabelnavn. Fra det jeg har sett, men det variable navnet, app, er en vanlig brukskonvensjon i de fleste Ember-apper, og anbefales faktisk for å gjøre det lettere å kopiere og lime inn mye av prøvekoden som blir opprettet i fellesskapet.
Med listen ovenfor, gjør Ember, via den ene linjen, i hovedsak denne koden for deg automatisk bak kulissene:
// Opprett søknadsnavnet mellomrom App = Ember.Application.create (); // Opprett den globale ruteren for å administrere sidestatus via URL-adresser App.Router.map (funksjon () ); // Opprett standardprogramrute for å angi statusnivå på applikasjonsnivå App.ApplicationRoute = Ember.Route.extend (); // Opprett standard applikasjonsmal
Så, mens startpakken ikke definerte eksplisitt en applikasjons-scoped-ruter, rute eller mal, sørget Ember for at de er opprettet og tilgjengelig slik at grunnlaget for appen din er satt og tilgjengelig for deg. Det er helt greit å eksplisitt lage koden. Faktisk kan det hende du vil gjøre det hvis du planlegger å sende data eller angi attributter for din forekomst av programobjektet.
Nå lurer du kanskje på at denne "søkemalen" automatisk blir gjengitt og hvorfor du ikke ser den inn index.html
. Det er fordi det er valgfritt å eksplisitt lage applikasjon mal. Hvis det er i markeringen, vil Ember umiddelbart gjengi det. Ellers fortsetter det å behandle andre deler av søknaden som vanlig. Den typiske brukssaken til applikasjon mal definerer globale, applikasjons-brede brukergrensesnittelementer, for eksempel topptekst og bunntekst.
Definere applikasjon mal bruker den samme stilsyntaxen som en hvilken som helst annen mal, unntatt med en liten forskjell: malnavnet trenger ikke spesifiseres. Så definerer du mal slik:
eller dette:
gir deg de samme nøyaktige resultatene. Ember tolker en mal uten data-mal-navn som søkemalen og vil gjøre det automatisk når programmet starter.
Hvis du oppdaterer index.html
ved å legge til denne koden:
Du ser nå at innholdet i toppteknappen vises øverst på innholdet i indeksmalen. Håndtakene Utløp Direktivet fungerer som plassholder i applikasjon mal, slik at Ember kan injisere andre maler i den (som fungerer som en pakke), og lar deg ha globale brukergrensesnittfunksjoner, for eksempel overskrifter og bunntekster som omgir innhold og funksjonalitet. Ved å legge til applikasjon mal til index.html
, du har instruert Ember til å:
Utløp
direktivindex
mal En viktig takeaway er at alt vi gjorde var å legge til en mal (applikasjon), og Ember tok umiddelbart vare på resten. Det er disse funksjonen bindinger som gjør Ember.js så kraftig rammeverk å jobbe med.
Ruting er uten tvil det vanskeligste konseptet å forstå i Ember, så jeg vil gjøre mitt beste for å bryte det ned til håndterbare trinn. Som bruker navigerer applikasjonen, må det være en metode for å administrere tilstanden til de ulike delene brukeren besøker. Det er der applikasjonens ruter og stedsspesifikke ruter kommer inn.
Ember-routerobjektet er det som styrer dette ved bruk av ruter som identifiserer ressursene som trengs for spesifikasjonssteder. Jeg liker å tenke på ruteren som trafikkansvarlig som leder biler (brukere) til forskjellige gater (URLer og ruter). Ruten, selv, er bundet til bestemte nettadresser, og når nettadressen er tilgjengelig, blir rutenes ressurser tilgjengelig.
Ser på JS / app.js
igjen, vil du legge merke til at det er opprettet en rute for rotsiden (index):
App.IndexRoute = Ember.Route.extend (setupController: funksjon (controller) controller.set ('content', ['rød', 'gul', 'blå']););
Det er imidlertid ingen ruteren forekomst. Husk at Ember vil opprette en ruter som standard hvis du ikke angir en. Det vil også opprette en standard ruteoppføring for roten til programmet som ligner dette:
App.Router.map (funksjon () this.resource ('index', path: '/'););
Dette forteller Ember at når roten til søknaden blir rammet, burde den laste ressursene til en ruteobjekt-instans som heter IndexRoute hvis den er tilgjengelig. Dette er grunnen til at, til tross for at ingen rutermodus blir deklarert, går applikasjonen fortsatt. Ember vet internt at ruten skal bli navngitt IndexRoute, vil se etter det, og laste dets ressurser, tilsvarende. I dette tilfellet oppretter det en kontroller som vil inneholde data som skal brukes i indeksmalen.
Siden nettadresser er nøkkelidentifikatorene som Ember bruker til å administrere tilstanden til søknaden din, vil hver enkelt ha sin egen rutehåndterer spesifisert hvis ressurser må lastes for den delen av appen. Her er hva jeg mener; anta at du har en app med tre seksjoner:
I de fleste tilfeller vil hver av disse seksjonene ha sine egne unike ressurser som må lastes (for eksempel data eller bilder). Så du vil opprette rutehåndterere ved hjelp av ressurs() Metode i Embers applikasjonsruterobjekteksempel som dette:
App.Router.map (funksjon () this.resource ('accounts'); this.resource ('profiler'); this.resource ('gallery'););
Dette tillater Ember å forstå strukturen i applikasjonen og administrere ressurser, tilsvarende. Rutedefinisjonene vil korrelere til individuelle ruteobjekt-forekomster som faktisk gjør tunge løft som å sette opp eller styre kontrollere:
App.GalleryRoute = Ember.Route.extend (setupController: funksjon (controller) controller.set ('content', ['pic-1.png', 'pic-2.png', 'pic-3.png' ]););
Så i eksemplet ovenfor, når en bruker besøker "/ gallery", kjører Ember.js GalleryRoute-ruteobjektet, konfigurerer en kontroller med data og gjengir galleri mal. Igjen, dette er grunnen til at navngivingskonvensjoner er så viktige i Ember.
Programmet ditt kan også ha nestede nettadresser, som / Konto / new
For disse tilfellene kan du definere Ember-ressurser som lar deg gruppere ruter sammen, slik som:
App.Router.map (funksjon () this.resource ('accounts', funksjon () this.route ('new');););
I dette eksemplet brukte vi ressurs()
metode for å gruppere ruter sammen og rute()
metode for å definere rutene i gruppen. Den generelle tommelfingerregelen er å bruke ressurs()
for substantiver (kontoer og konto vil begge være ressurser, selv når det er nestet) og rute()
for modifikatorer: (verb som ny
og redigere
eller adjektiver som favoritter
og hovedrollen
).
Bortsett fra å gruppere ruter, bygger Ember interne referanser til kontrollerne, ruter og maler for hver av de spesifiserte gruppene. Slik ser det ut (og igjen berører det Embers navnekonvensjoner):
"/ kontoer":
"/ Regnskap / new":
Når en bruker besøker "/ accounts / new", er det litt av et foreldre / barn eller master / detalj scenario som oppstår. Ember vil først sikre at ressursene for kontoer er tilgjengelige og gjengi kontoer mal (dette er hoveddelen av det). Deretter vil det følge opp og gjøre det samme for "/ accounts / new", sette opp ressurser og gjengi accounts.new mal.
Legg merke til at ressurser også kan nestes for mye dypere URL-strukturer, slik som dette:
App.Router.map (funksjon () this.resource ('accounts', funksjon () this.route ('new'); this.resource ('pictures', function () this.route ('add' ););;);
Jeg har dekket mye materiale i dette innlegget. Forhåpentligvis har det hjulpet for å forenkle noen av aspektene av hvordan en Ember-applikasjon fungerer og hvordan ruter fungerer.
Vi er fortsatt ikke ferdige, skjønt. I neste oppføring vil jeg dykke inn i Embers funksjoner for å trekke tilbake data og gjøre den tilgjengelig med appen din. Det er her modellene og kontrollerne kommer inn, så vi vil fokusere på å forstå hvordan de to jobber sammen.