Kuna tänapäevased veebirakendused teevad üha enam kliendipoolseid külgi (tõsiasi, et nimetame neid nüüd 'veebirakendusteks', mitte 'veebisaitideks', on huvi kliendipoolsete raamistike vastu kasvanud . Selles valdkonnas on palju mängijaid, kuid paljude funktsionaalsuste ja paljude liikuvate osadega rakenduste puhul paistavad neist silma eriti kaks: Angular.js ja Ember.js .
Avaldasime juba põhjaliku [Angular.js õpetuse] [https://www.toptal.com/angular-js/a-step-by-step-guide-to-your-first-angularjs-app], nii et keskendume selles postituses Ember.js-le, kus me ehitame teie muusikakogu kataloogimiseks lihtsa Emberi rakenduse. Tutvustatakse raamistiku peamisi ehitusplokke ja saate pilgu selle kujunduspõhimõtetele. Kui soovite lugemise ajal lähtekoodi näha, on see saadaval järgmiselt rock-and-roll Githubis .
Meie Rock & Rolli rakendus näeb välja selle lõplikus versioonis järgmiselt:
Vasakul näete, et meil on nimekiri artistidest ja paremal nimekiri valitud esitaja lauludest (näete ka, et mul on hea muusikamaitse, kuid ma kaldun kõrvale). Uusi esitajaid ja laule saab lisada, lihtsalt sisestades tekstikasti ja vajutades kõrval olevat nuppu. Iga laulu kõrval olevad tähed annavad sellele hinnangu, à la iTunes.
Võime jaotada rakenduse algfunktsioonid järgmisteks sammudeks:
Selle toimimiseks on meil veel pikk tee minna, nii et alustame.
Emberi üks eripära on URL-idele suur rõhk. Paljudes teistes raamistikes puudub eraldi URL-ide olemasolu eraldi ekraanide jaoks või see on tagantjärele mõeldud. Emberis on ruuter - komponent, mis haldab URL-e ja nende vahelisi üleminekuid - keskne tükk, mis koordineerib ehitusplokkide vahelist tööd. Järelikult on see ka võti Emberi rakenduste sisemise töö mõistmiseks.
Siin on meie rakenduse marsruudid:
App.Router.map(function() { this.resource('artists', function() { this.route('songs', { path: ':slug' }); }); });
Määratleme ressursi marsruudi artists
ja a songs
selle sees pesitsetud marsruut. See määratlus annab meile järgmised marsruudid:
Kasutasin suurepärast pistikprogrammi Ember Inspector (see on olemas mõlemale versioonile) Chrome ja Firefox ), et näidata loodud marsruute hõlpsasti loetaval viisil. Siin on Emberi marsruutide põhireeglid, mida saate ülaltoodud tabeli abil meie konkreetsel juhul kontrollida:
On olemas kaudne application
tee.
See aktiveeritakse kõik taotlused (üleminekud).
On olemas kaudne index
tee.
See sisestatakse siis, kui kasutaja navigeerib rakenduse juure.
Iga ressursi marsruut loob sama nimega marsruudi ja loob selle all kaudselt indeksi marsruudi.
See indeks marsruut aktiveeritakse, kui kasutaja navigeerib marsruudile. Meie puhul artists.index
käivitatakse, kui kasutaja navigeerib /artists
.
Lihtsal (ressursivälisel) sisestatud marsruudil on selle eesliide vanema marsruudi nimi.
Meie määratletud marsruut this.route('songs', ...)
on artists.songs
selle nimeks. See käivitatakse, kui kasutaja navigeerib /artists/pearl-jam
või /artists/radiohead
.
Kui rada pole antud, eeldatakse, et see võrdub marsruudi nimega.
Kui tee sisaldab :
, loetakse see dünaamiliseks segmendiks .
Sellele määratud nimi (meie puhul slug
) vastab URL-i vastavas segmendis olevale väärtusele. slug
ülaloleval segmendil on väärtus pearl-jam
, radiohead
või mis tahes muu väärtus, mis URL-ist välja võeti.
Esimese sammuna ehitame ekraani, mis kuvab vasakul olevate kunstnike loendi. Seda ekraani tuleks näidata kasutajatele, kui nad navigeerivad saidile /artists/
Selle ekraani renderdamise mõistmiseks on aeg tutvustada veel ühte inimese üldist disainiprintsiipi: kokkulepe konfiguratsiooni üle . Ülaltoodud jaotises nägime, et /artists
aktiveerib artists
tee. Kokkuleppeliselt selle marsruudi nimi objekt on ArtistsRoute
. Selle marsruudi objekti ülesandeks on rakenduse renderdamiseks andmete hankimine. See juhtub marsruudi mudeli konksus:
App.ArtistsRoute = Ember.Route.extend({ model: function() { var artistObjects = []; Ember.$.getJSON('http://localhost:9393/artists', function(artists) { artists.forEach(function(data) { artistObjects.pushObject(App.Artist.createRecord(data)); }); }); return artistObjects; } });
Selles katkendis tõmmatakse andmed XHR-kõne kaudu tagantpoolt ja pärast mudeliobjektiks teisendamist lükatakse see massiivi, mida saame seejärel kuvada. Kuid marsruudi reageerimisvõime ei laiene kuvariloogika pakkumisele, mida kontroller haldab. Vaatame järele.
Hmmm - tegelikult ei pea me siinkohal kontrollerit määratlema! Ember on kontrolleri genereerimiseks piisavalt tark kui vaja ja määrake kontrolleri M.odel
atribuut mudeli konksu enda tagastusväärtusele, nimelt artistide nimekirjale. (See on jällegi paradigma „konfiguratsiooni üle kokkuleppimine” tulemus.) Loendi kuvamiseks võime astuda ühe kihi alla ja luua malli:
{{#each model}} {{#link-to 'artists.songs' this class='list-group-item artist-link'}} {{name}} {{/link-to}} {{/each}} {{outlet}}
Kui see tundub tuttav, siis sellepärast, et Ember.js kasutab Juhtraud mallid, millel on väga lihtne süntaks ja abimehed, kuid mis ei võimalda mitte triviaalset loogikat (nt ORing- või ANDing-terminid tingimuslikult).
Ülaltoodud mallis kordame mudeli (mis on varem seatud kõiki esitajaid sisaldava massiivi marsruudi järgi) ja renderdame iga selle elemendi jaoks lingi, mis viib meid artists.songs
selle kunstniku marsruut. Link sisaldab esitaja nime. #each
abimees juhtraual muudab selle sees oleva ulatuse praeguseks üksuseks, nii et {{name}}
viitab alati kunstniku nimele, kes on praegu itereerimisel.
Veel üks huvipakkuv punkt ülaltoodud katkendis: {{outlet}}
, mis määrab malli pesad, kus sisu saab renderdada. Marsruutide pesitsemisel renderdatakse kõigepealt välise, ressursimarsruuti mall, millele järgneb sisemine marsruut, mis muudab selle malli sisu {{outlet}}
määratletud välise marsruudiga. Täpselt nii juhtub siin.
Kokkuleppe kohaselt muudavad kõik marsruudid oma sisu samanimeliseks malliks. Ülal on data-template-name
ülaltoodud malli atribuut on artists
mis tähendab, et see renderdatakse välisel marsruudil artists
. See määrab parempoolse paneeli sisu väljalaskeava, kuhu sisemine marsruut artists.index
muudab selle sisu:
Select an artist.
Kokkuvõtteks võib öelda, et üks marsruut (artists
) renderdab selle sisu vasakul külgribal, selle mudel on esitajate loend. Teine marsruut, artists.index
esitab oma sisu artists
pakutud pesasse mall. See võib tuua mõned andmed, mida selle mudeliks kasutada, kuid sel juhul tahame kuvada ainult staatilist teksti, nii et meil pole seda vaja.
Järgmisena soovime, et saaksime luua kunstnikke, mitte ainult vaadata igavat nimekirja.
Kui ma seda näitasin artists
kunstnike loetelu renderdav mall, ma pettsin natuke. Lõikasin ülemise osa välja, et keskenduda olulisele. Nüüd lisan selle tagasi:
{{input type='text' class='new-artist' placeholder='New Artist' value=newName}} Add ...
Lihtsa tekstisisestuse renderdamiseks kasutame Emberi abistajat input
Selles me siduma newName
tekstisisestuse väärtus selle malli varundava kontrolleri omadus ArtistsController
. Selle tagajärjel, kui sisendi väärtuse omadus muutub (teisisõnu, kui kasutaja sisestab sinna teksti), newName
kontrolleri omadust hoitakse sünkroonis.
Samuti anname teada, et createArtist
toiming tuleks käivitada, kui nupule klõpsatakse. Lõpuks seome nupu keelatud atribuudi disabled
-ga kontrolleri omadus. Mis siis kontroller välja näeb?
App.ArtistsController = Ember.ArrayController.extend({ newName: '', disabled: function() { return Ember.isEmpty(this.get('newName')); }.property('newName') });
newName
on alguses tühi, mis tähendab, et tekstisisestus jääb tühjaks. (Pidage meeles, mida ma sidumiste kohta rääkisin? Proovige muuta newName
ja näete, et see kajastuks sisendvälja tekstina.)
disabled
on rakendatud nii, et kui sisestuskastis pole teksti, naaseb see true
ja seega keelatakse nupp. .property
kõne lõpus muudab selle 'arvutatud omaduseks', mis on veel üks suurepärane viil Emberi koogist.
Arvutatud omadused on omadused, mis sõltuvad muudest omadustest, mis võivad ise olla 'normaalsed' või arvutatud. Ember paneb nende väärtuse vahemällu, kuni üks sõltuvatest omadustest muutub. Seejärel arvutab see arvutatud atribuudi väärtuse ümber ja teeb selle uuesti vahemällu.
Siin on ülaltoodud protsessi visuaalne esitus. Kokkuvõtteks: kui kasutaja sisestab esitaja nime, siis newName
kinnisvara värskendused, millele järgneb disabled
vara ja lõpuks lisatakse loendisse ka kunstniku nimi.
Mõelge korraks sellele. Sidumiste ja arvutatud omaduste abil saame (mudeli) andmed luua kui üks tõeallikas . Eespool käivitab uue esitaja nime muutus kontrolleri atribuudi muutuse, mis omakorda käivitab puudega atribuudi muutuse. Kui kasutaja hakkab uue esitaja nime tippima, saab nupp justkui võluväel sisse.
Mida suurem on süsteem, seda rohkem võimendust saame „tõe ühe allika” põhimõttest. See hoiab meie koodi puhtana ja usaldusväärsena ning kinnisvara definitsioonid deklaratiivsemalt.
Mõnes teises raamistikus rõhutatakse ka seda, et mudelandmed oleksid tõe ainus allikas, kuid kas need ei lähe Emberini või ei tee nii põhjalikku tööd. Näiteks nurgal on kahesuunalised sidemed - kuid sellel pole arvutatud omadusi. See võib arvutatud omadusi lihtsate funktsioonide abil 'jäljendada'; siin on probleem selles, et tal pole võimalust teada saada, millal „arvutatud vara” värskendada, ja seega pöördutakse räpase kontrolli poole ning see omakorda toob kaasa jõudluskao, eriti suurtes rakendustes.
Kui soovite selle teema kohta rohkem teada saada, soovitan teil lugeda eviltrouti blogipostitus lühema versiooni jaoks või see Quora küsimus pikema arutelu jaoks, milles kaaluvad mõlema poole põhiarendajad.
Läheme tagasi vaatama, kuidas createArtist
toiming luuakse pärast selle käivitamist (pärast nupuvajutust):
App.ArtistsRoute = Ember.Route.extend({ ... actions: { createArtist: function() { var name = this.get('controller').get('newName'); Ember.$.ajax('http://localhost:9393/artists', { type: 'POST', dataType: 'json', data: { name: name }, context: this, success: function(data) { var artist = App.Artist.createRecord(data); this.modelFor('artists').pushObject(artist); this.get('controller').set('newName', ''); this.transitionTo('artists.songs', artist); }, error: function() { alert('Failed to save artist'); } }); } } });
Tegevuskäitlejad tuleb pakkida actions
objekt ja seda saab määratleda marsruudil, kontrolleril või vaates. Valisin selle siin marsruudil määratleda, kuna tegevuse tulemus ei piirdu kontrolleriga, vaid pigem 'globaalne'.
Siin pole midagi uhket toimumas. Pärast seda, kui taustteave teatas meile, et salvestustoiming on edukalt lõpule viidud, teeme kolm asja järjekorras:
newName
abil siduv, säästes meid otsese DOM-i manipuleerimise vajadusest.artists.songs
), sisestades värskelt loodud kunstniku selle marsruudi mudelina. transitionTo
on viis sisemiselt marsruutide vahel liikumiseks. (Abistaja link-to
aitab seda teha kasutaja toimingu kaudu.)Esitamiseks mõeldud laule saame kuvada esitaja nimel klõpsates. Möödume ka kunstnikust, kellest saab uue marsruudi mudel. Kui mudeliobjekt nõnda edasi antakse, siis model
marsruudi konksu ei kutsuta, kuna mudelit pole vaja lahendada.
Aktiivne marsruut on siin artists.songs
ja seega saavad kontroller ja mall olema ArtistsSongsController
ja artists/songs
Me nägime juba, kuidas mall renderdatakse artists
pakutud väljundisse malli, et saaksime keskenduda vaid käsil olevale mallile:
(...) {{#each songs}} {{title}} {{view App.StarRating maxRating=5}} {{/each}}
Pange tähele, et eemaldasin uue loo loomiseks koodi, kuna see oleks täpselt sama mis uue esitaja loomisel.
songs
atribuut on kõigis esitajaobjektides seadistatud serveri tagastatud andmetest. Täpne mehhanism, kuidas seda tehakse, pakub praegusele arutelule vähe huvi. Praegu piisab sellest, kui teame, et igal laulul on pealkiri ja hinnang.
Pealkiri kuvatakse otse mallis ja hinnangut tähistatakse tähtedega StarRating
kaudu vaade. Vaatame seda nüüd.
Laulu hinnang jääb vahemikku 1–5 ja kuvatakse kasutajale vaate kaudu App.StarRating
. Vaatel on juurdepääs nende kontekstile (antud juhul laulule) ja kontrollerile. See tähendab, et nad saavad selle omadusi lugeda ja muuta. See on vastupidine teise Emberi ehitusplokile, komponentidele, mis on isoleeritud, korduvkasutatavad juhtnupud, millel on juurdepääs ainult neile edastatavale. (Ka selles näites võiksime kasutada tärnide hindamise komponenti.)
Vaatame, kuidas vaates kuvatakse tärnide arv ja määratakse loo hinnang, kui kasutaja klõpsab ühel tärnil.
App.StarRating = Ember.View.extend({ classNames: ['rating-panel'], templateName: 'star-rating', rating: Ember.computed.alias('context.rating'), fullStars: Ember.computed.alias('rating'), numStars: Ember.computed.alias('maxRating'), stars: function() { var ratings = []; var fullStars = this.starRange(1, this.get('fullStars'), 'full'); var emptyStars = this.starRange(this.get('fullStars') + 1, this.get('numStars'), 'empty'); Array.prototype.push.apply(ratings, fullStars); Array.prototype.push.apply(ratings, emptyStars); return ratings; }.property('fullStars', 'numStars'), starRange: function(start, end, type) { var starsData = []; for (i = start; i <= end; i++) { starsData.push({ rating: i, full: type === 'full' }); }; return starsData; }, (...) });
rating
, fullStars
ja numStars
on arvutatud omadused, mida arutasime eelnevalt disabled
ArtistsController
vara. Eespool kasutasin nn arvutatud omaduste makrot, millest kümmekond on määratletud Emberis. Need muudavad tüüpilised arvutatud omadused lühemaks ja vähem vigadele altid (kirjutama). Seadsin rating
konteksti (ja seeläbi ka laulu) hinnanguks, samal ajal kui mina määratlesin mõlemad fullStars
ja numStars
omadused, et need saaksid tärnide vidina kontekstis paremini lugeda.
stars
meetod on peamine atraktsioon. See tagastab tähtede massiivi, milles iga üksus sisaldab rating
omadus (vahemikus 1 kuni 5) ja lipp (full
) tähistamaks, kas täht on täis. See muudab nende malli läbimise ülimalt lihtsaks:
{{#each view.stars}}
{{/each}} See koodilõik sisaldab mitmeid märkusi:
each
helper tähistab, et ta kasutab vaate atribuuti (erinevalt kontrolleri omadusest), lisades atribuudi nimele view
.class
span-sildi atribuudil on määratud dünaamilised ja staatilised klassid. Kõik, mille eesliide on :
muutub staatiliseks klassiks, samas kui full:glyphicon-star:glyphicon-star-empty
tähistamine on nagu kolmeastmeline operaator JavaScriptis: kui kogu vara vastab tõele, tuleks omistada esimene klass; kui ei, siis teine.setRating
tegevus tuleks käivitada - kuid Ember otsib seda vaates, mitte marsruudilt või kontrollerilt, nagu uue kunstniku loomisel.Seega määratletakse tegevus vaates:
App.StarRating = Ember.View.extend({ (...) actions: { setRating: function() { var newRating = $(event.target).data('rating'); this.set('rating', newRating); } } });
Hinnangu saame rating
-st andmete atribuut, mille määrasime mallis ja määrasime selle siis rating
laulu jaoks. Pange tähele, et uus hinne ei jää taustal püsima. Seda funktsionaalsust ei oleks keeruline rakendada lähtuvalt sellest, kuidas me kunstniku lõime ja see jäetakse motiveeritud lugeja harjutuseks.
Oleme maitsnud mitmeid eelmainitud Emberi koogi koostisosi:
Ilus, kas pole?
Emberi on palju rohkem, kui ma selle postituse jaoks üksi mahuksin. Kui soovite näha ekraanikuva seeriat selle kohta, kuidas ma ülaltoodud rakenduse mõnevõrra arenenuma versiooni ehitasin ja / või Emberi kohta lisateavet saate, registreeru minu meililistile artiklite või näpunäidete saamiseks nädala kaupa.
Loodan, et olen äratanud teie isu Ember.js-i kohta lisateabe saamiseks ja et te lähete kaugemale näidisrakendusest, mida olen selles postituses kasutanud. Jätkates Ember.js-i tundmaõppimist, vaadake kindlasti pilk meie poole artikkel Ember Data kohta, et õppida, kuidas Ember-andmekogu kasutada . Head ehitamist!
Seotud: Ember.js ja 8 levinumat viga, mida arendajad teevad