Intrarea în Ember.js Pașii următori

În articolul meu introductiv, am analizat elementele de bază ale cadrului Ember.js și conceptele fundamentale pentru construirea unei aplicații Ember. În acest articol de urmărire, vom aborda mai adânc anumite domenii ale cadrului pentru a înțelege câte funcții lucrează împreună pentru a rezuma complexitatea dezvoltării unei singure pagini.


O aplicație de bază

Am remarcat anterior că cel mai simplu mod de a obține fișierele de care aveți nevoie este să mergeți la repo-ul Ember.js Github și să trageți în jos kit-ul de pornire, și acest lucru rămâne valabil. Acest kit de boilerplate include toate fișierele de care veți avea nevoie pentru a vă lansa experiența dvs. Ember, deci asigurați-vă că descărcați-l din acest articol.

Lucrul interesant este că setul de pornire este, de asemenea, un exemplu excelent al unei aplicații Ember de bază. Să mergem prin ea pentru a înțelege ce se întâmplă. Rețineți că voi sătura mai adânc în anumite zone mai târziu, așa că nu vă faceți griji dacă ceva nu are sens imediat în această secțiune. Este mai mult pentru a vă oferi o înțelegere la nivel înalt a funcționalității înainte de a vă scufunda în detalii.

Deschis index.html în browserul dvs. și veți vedea următoarele:

Bun venit la Ember.js

  • roșu
  • galben
  • albastru

Acest lucru nu este foarte interesant, știu, dar dacă te uiți la codul care a făcut acest lucru, vei vedea că sa făcut cu foarte puțin efort. Dacă ne uităm la "js / app.js", vedem următorul cod:

App = Ember.Application.create (); App.IndexRoute = Ember.Route.extend (setupController: funcție (controler) controller.set ('conținut', ['roșu', 'galben', 'albastru']);

La nivelul său cel mai de bază, o aplicație Ember are nevoie doar de această linie pentru a fi considerată tehnic o "aplicație":

App = Ember.Application.create ();

Acest cod stabilește o instanță a obiectului aplicației Ember, împreună cu un șablon de aplicație implicit, ascultători de evenimente și router de aplicații. Luați o secundă și încercați să vă gândiți la codul pe care trebuie să-l scrieți în mod normal pentru a crea un spațiu de nume global, un șablon de pe partea clientului, pentru a interacționa cu utilizatorii globali și a include istoricul și managementul de stat în codul dvs. Da, acea linie face toate astea. Să fim clari, totuși: Nu spun că face tot munca pentru tine, ci creează fundația pe care o vei construi, printr-o singură metodă de apel.

Următorul set de coduri stabilește comportamentul unei rute, în acest caz, pentru principalul index.html pagină:

App.IndexRoute = Ember.Route.extend (setupController: funcție (controler) controller.set ('conținut', ['roșu', 'galben', 'albastru']);

Rețineți că rutele sunt utilizate pentru a gestiona resursele asociate cu o anumită adresă URL în cadrul aplicației și permit companiei Ember să urmărească diferitele stări ale paginilor individuale. Adresa URL este identificatorul cheie pe care Ember îl folosește pentru a înțelege care dintre starea aplicației trebuie prezentată utilizatorului.

În acest caz, ruta rădăcină este creată implicit în Ember. De asemenea, aș fi putut defini în mod explicit traseul astfel:

App.Router.map (funcția () this.resource ('index', path: '/'); // ne duce la "/");

Dar Ember se ocupă de asta pentru mine pentru "rădăcina" cererii mele. Vom aborda rutele în detaliu mai târziu.

Revenind la următorul cod:

App.IndexRoute = Ember.Route.extend (setupController: funcție (controler) controller.set ('conținut', ['roșu', 'galben', 'albastru']);

În acest caz, atunci când un utilizator atinge rădăcina site-ului, Ember va configura un controler care va încărca un set de date de probă cu un nume semantic, numit conţinut. Aceste date pot fi ulterior utilizate în aplicație, prin intermediul acestui controler care utilizează acest nume. Și asta se întâmplă în mod specific index.html. Deschideți fișierul și veți găsi următoarele:

Acesta este un șablon din partea clientului Handlebars. Amintiți-vă că Handlebars este biblioteca templating pentru Ember și că este vital să creați interfețe de utilizator bazate pe date pentru aplicația dvs. Ember utilizează atribute de date pentru a conecta aceste șabloane la controlorii care gestionează datele dvs., fie că sunt specificați printr-un traseu sau ca un controler independent.

În ultimul meu articol, am menționat că convențiile de numire sunt importante în Ember și că ele fac ușor facilitățile de conectare. Dacă te uiți la codul șablonului, vei vedea că numele șablonului (specificat prin Date-șablon de nume- atribut) este "index". Acest lucru este intenționat și are scopul de a facilita conectarea la controlerul specificat pe ruta cu același nume. Dacă ne uităm din nou la codul de traseu, veți vedea că se numește "IndexRoute", iar în interiorul acestuia este un controler cu setarea de date:

App.IndexRoute = Ember.Route.extend (setupController: funcție (controler) controller.set ('conținut', ['roșu', 'galben', 'albastru']);

Controlorul stabilește o sursă de date numită "conținut" și o încarcă cu o serie de șiruri de caractere pentru culori. Practic, matricea este modelul dvs., iar controlerul este folosit pentru a expune acele atribute ale modelului.

Conceptele de numire permit Ember să conecteze resursele acestei rute (de exemplu: controlerul cu date) cu șablonul specificat cu același nume. Aceasta permite accesului șablonului la datele expuse de controlor, astfel încât acesta să poată fi utilizat prin intermediul directivelor Handlebars. De acolo, elementele din matrice sunt looped over using Handlebars ' fiecare directivă și specificând aliasul model care indică sursa de date:

#pentru orice element din model 
  • articol
  • /fiecare

    Pentru a fi mai precis, datele sunt populate în elemente de listă create dinamic, generând astfel marcajul pentru dvs. în zbor. Aceasta este frumusețea șabloanelor de pe partea clientului.

    Cred că această aplicație de bază evidențiază modul în care Ember abstractează multe lucruri pentru dvs. Este totuși un pic de magie neagră și nu este întotdeauna ușor să înțelegi cum funcționează lucrurile. Asta sa întâmplat de fapt cu mine și lucrurile nu au făcut destul de mult clic la început. Odată ce începeți să înțelegeți relațiile dintre diferitele componente ale cadrului, acesta începe să aibă mai mult sens. Să începem de la bază pentru a înțelege mai bine acest lucru.


    Pornind de la Ground Up

    Am atins pe scurt obiectul aplicației Ember și faptul că construiește baza pentru aplicația dvs. Ghizii Ember fac o treabă excelentă de a sublinia în mod specific ce reprezintă instanța unui obiect de aplicație Ember:

    • Setează spațiul de nume al aplicației. Toate clasele din aplicația dvs. vor fi definite ca proprietăți pe acest obiect (de ex. App.PostsView și App.PostsController). Acest lucru contribuie la prevenirea poluării domeniului global.
    • Adăugă ascultători de evenimente în document și este responsabil pentru trimiterea evenimentelor la vizualizările dvs..
    • Realizează automat șablonul de aplicație, cel mai rădăcină șablon, în care celelalte șabloane vor fi redate.
    • Se creează automat un router și începe rutarea, pe baza adresei URL actuale.

    Deci, această afirmație simplă:

    App = Ember.Application.create ();

    conectează o tona întreagă de piese fundamentale pe care va depinde cererea dumneavoastră. Este important să rețineți asta App nu este un cuvânt cheie în Ember. Este o variabilă globală normală pe care o utilizați pentru a defini spațiul de nume și ar putea fi orice nume de variabilă valabil. Din ceea ce am văzut, totuși, numele variabilei, App, este o convenție frecvent utilizată în majoritatea aplicațiilor Ember și este de fapt recomandată pentru a face mai ușor copierea și lipirea o mare parte a eșantionului de cod creat în comunitate.

    Luând lista de mai sus, ceea ce face Ember, prin acea linie, este în esență crearea acestui cod pentru tine în mod automat în spatele scenei:

    // Creați spațiul de nume al aplicației App = Ember.Application.create (); // Creați routerul global pentru a gestiona starea paginii prin intermediul adreselor URL App.Router.map (function () ); // Creați calea implicită a aplicației pentru a seta proprietățile de stare la nivel de aplicație App.ApplicationRoute = Ember.Route.extend (); // Creați șablonul de aplicație implicit 

    Deci, în timp ce setul de pornire nu a definit în mod explicit un router, ruta sau șablon cu aplicație, Ember a asigurat că acestea sunt create și disponibile astfel încât fundația aplicației dvs. să fie setată și disponibilă pentru dvs. Este cu siguranță bine să creați în mod explicit codul. De fapt, ați putea dori să faceți acest lucru dacă intenționați să transmiteți date sau să setați atribute pentru instanța obiectului aplicației.

    Acum s-ar putea să vă întrebați că acest "șablon de aplicare" se obține automat și de ce nu îl vedeți index.html. Asta pentru că este opțional să creezi în mod explicit cerere șablon. Dacă e în marcaj, Ember o va face imediat. În caz contrar, acesta procesează alte părți ale aplicației dvs. ca de obicei. Cazul tipic de utilizare pentru cerere șablon definește elemente de interfață utilizator la nivel global, aplicații, cum ar fi antetul și subsolurile.

    Definirea cerere șablonul folosește aceeași sintaxă de stil ca orice alt șablon, cu excepția unei mici diferențe: numele șablonului nu trebuie specificat. Deci, definirea șablonului dvs. astfel:

     

    sau asta:

     

    vă oferă aceleași rezultate exacte. Ember va interpreta un șablon cu nr Date-șablon de nume- ca șablon de aplicație și îl va afișa automat când începe aplicația.

    Dacă actualizați index.html prin adăugarea acestui cod:

     

    Veți vedea acum că conținutul etichetei de antet apare în partea de sus a conținutului șablonului index. Manerele Priză directiva servește ca un loc de substituție în cerere șablon, permițând ember-ului să injecteze alte șabloane în el (care servesc ca un înveliș de fel) și vă permite să aveți caracteristici UI globale, cum ar fi anteturile și subsolurile care înconjoară conținutul și funcționalitatea. Prin adăugarea cerere șablon pentru index.html, l-ai instruit pe Ember să:

    • Executa automat cerere șablon
    • Injectați șablonul index în cerere șablon prin intermediul ghidonului Priză directivă
    • Imediat procesați și faceți index șablon

    O importanță importantă este că tot ce am făcut a fost să adăugăm un șablon (cerere), iar Ember avea grijă imediat de restul. Acestea sunt legăturile caracteristice care fac ca Ember.js să funcționeze cu un astfel de cadru puternic.


    Configurarea rutelor

    Routing-ul este, probabil, cel mai dificil concept de înțeles în Ember, așa că voi face tot posibilul pentru a-l rupe până la pași ușor de manevrat. Când un utilizator navighează aplicația dvs., trebuie să existe o metodă pentru gestionarea stării diferitelor părți pe care le vizitează utilizatorul. Aici intră router-ul aplicației și rutele specifice locației.

    Obiectul ruterului Ember este cel care gestionează acest lucru prin utilizarea unor rute care identifică resursele necesare locațiilor de specificații. Îmi place să mă gândesc la router ca polițist de trafic care direcționează mașinile (utilizatorii) spre străzi diferite (adrese URL și rute). Rutele, ele insele, sunt legate de anumite adrese URL și, atunci când URL-ul este accesat, resursele de rute sunt puse la dispoziție.

    Uitandu-ma la js / app.js din nou, veți observa că a fost creat un traseu pentru pagina rădăcină (index):

    App.IndexRoute = Ember.Route.extend (setupController: funcție (controler) controller.set ('conținut', ['roșu', 'galben', 'albastru']);

    Cu toate acestea, nu există o instanță a routerului. Rețineți că Ember va crea un router în mod prestabilit dacă nu specificați unul. De asemenea, va crea o intrare de rutare implicită pentru rădăcina aplicației similară cu aceasta:

    App.Router.map (funcția () this.resource ('index', path: '/'););

    Acest lucru îi spune lui Ember că, atunci când rădăcina aplicației este lovită, ar trebui să încarce resursele unei instanțe de obiect de traseu numite IndexRoute dacă este disponibil. De aceea, în ciuda faptului că nu a fost declarată nicio instanță de router, aplicația încă rulează. Ember știe intern că traseul rădăcinii ar trebui să fie numit IndexRoute, va căuta și va încărca resursele în consecință. În acest caz, se creează un controler care va conține date care vor fi utilizate în șablonul index.

    Întrucât adresele URL sunt identificatorii cheie pe care Ember le utilizează pentru a gestiona starea aplicației dvs., fiecare va avea, în general, propriul handler de rută specificat dacă resursele trebuie să fie încărcate pentru acea secțiune a aplicației. Iată ce vreau să spun; să presupunem că aveți o aplicație cu trei secțiuni:

    • Cont: (URL: / cont)
    • Profil (URL: / profil)
    • Galerie (URL: / galerie)

    În majoritatea cazurilor, fiecare dintre aceste secțiuni va avea propriile resurse unice care trebuie încărcate (de exemplu: date sau imagini). Deci, ați crea manageri de rută folosind resursă() în cadrul aplicației de obiecte a routerului Ember, cum ar fi:

    App.Router.map (funcția () this.resource ('accounts'); această sursă ('profiles'); this.resource ('galerie'););

    Aceasta permite companiei Ember să înțeleagă structura aplicației și să gestioneze resursele în consecință. Definițiile rutelor vor fi corelate cu exemplele de obiecte ale traseelor ​​individuale care efectuează de fapt reglajele de configurare sau interfață de ridicare similare:

    App.GalleryRoute = Ember.Route.extend (setupController: funcție (controler) controller.set ('content', ['pic-1.png', 'pic-2.png' ]););

    Astfel, în exemplul de mai sus, atunci când un utilizator vizitează "/ galerie", Ember.js instantează obiectul rutei GalleryRoute, configurează un controler cu date și redă Galerie șablon. Din nou, de aceea convențiile de numire sunt atât de importante în Ember.

    Aplicația dvs. poate avea și adrese URL imbricate, cum ar fi / Cont / nou

    Pentru aceste instanțe, puteți defini resursele Ember care vă permit să grupați rute împreună, cum ar fi:

     App.Router.map (funcția () this.resource ('conturi', funcția () this.route ('new');););

    În acest exemplu, am folosit resursă() - metoda de grupare a traseelor ​​împreună și - traseu() metoda de definire a rutelor din cadrul grupului. Regula generală este de a utiliza resursă() pentru substantive (conturile și contul ar fi ambele resurse chiar și atunci când sunt imbricate) și traseu() pentru modificatori: (verbe ca nou și Editați | × sau adjective ca favorite și a jucat).

    Pe lângă gruparea rutelor, Ember construiește referințe interne la controlerele, rutele și șabloanele pentru fiecare rutare de grup specificată. Așa ar arăta (și din nou se referă la convențiile de numire ale lui Ember):

    "/conturi":

    • Controlor: AccountsController
    • Traseu: AccountsRoute
    • Format: conturi (da, este mică)

    "/ Conturi / noi":

    • Controlor: AccountsNewController
    • Traseu: AccountsNewRoute
    • Format: conturi / noi

    Când un utilizator vizitează "/ accounts / new", există un scenariu parental / copil sau master / detaliu care apare. Ember va asigura mai întâi că resursele pentru conturi sunt disponibile și fac conturi șablon (aceasta este partea principală a acestuia). Apoi, va urmări și va face același lucru pentru "/ accounts / new", configurarea resurselor și redarea accounts.new șablon.

    Rețineți că resursele pot fi de asemenea imbricate pentru structuri URL mult mai profunde, cum ar fi:

     Aplicații.Router.map (funcția () this.resource ('accounts', function () this.route ('new'); this.resource (' ););););

    Pasii urmatori

    Am acoperit o mulțime de materiale în acest post. Sperăm că a contribuit la simplificarea unor aspecte legate de modul în care funcționează o aplicație Ember și cum funcționează rutele.

    Încă nu am terminat. În următoarea intrare, mă voi arunca în captivitatea lui Ember pentru a retrage datele și a le pune la dispoziție împreună cu aplicația. Aici intră modelele și controlorii, așa că ne vom concentra pe înțelegerea modului în care cei doi lucrează împreună.

    Cod