Dit is deel twee van een driedelige serie die u leert hoe u een applicatie voor contactbeheer in JavaScript bouwt met behulp van CanJS en jQuery. Als je klaar bent met deze tutorial, heb je alles wat je nodig hebt om je eigen JavaScript-applicaties te bouwen met CanJS!
In deel één hebt u de modellen, weergaven en bedieningselementen gemaakt die nodig zijn om contacten en gebruikte fixtures weer te geven om een REST-service te simuleren.
In dit deel, zult u:
Je zult vanaf het eerste deel aan de bronbestanden toevoegen, dus als je dat nog niet hebt gedaan, ga je eerst inhalen. Ik ben er als je klaar bent.
Routing helpt bij het beheren van de browsergeschiedenis en de clientstatus in Javascript-toepassingen met één pagina.
Routing helpt bij het beheren van de browsergeschiedenis en de clientstatus in Javascript-toepassingen met één pagina. De hash in de URL bevat eigenschappen die een toepassing leest en schrijft. Verschillende delen van de app kunnen naar deze wijzigingen luisteren en dienovereenkomstig reageren, meestal delen van de huidige pagina bijwerken zonder een nieuwe te laden.
can.route
is een speciale waarneembaar die updates en reageert op veranderingen in window.location.hash
. Gebruik can.route
om URL's toe te wijzen aan eigenschappen, wat resulteert in mooie URL's zoals #! Filter / all
. Als er geen routes zijn gedefinieerd, wordt de hash-waarde gewoon geserialiseerd in URL-gecodeerde notatie zoals #! Categorie = all
.
In deze toepassing wordt routering gebruikt om contactpersonen per categorie te filteren. Voeg de volgende code toe aan uw contacts.js
het dossier:
can.route ('filter /: category') can.route (", category: 'all')
De eerste regel maakt een route met een categorie
eigenschap die uw toepassing kan lezen en schrijven. De tweede regel maakt een standaardroute, waarmee de categorie
eigendom aan allemaal
.
EEN Model.List
is een waarneembare reeks modelinstanties. Wanneer u een definieert Model
net zoals Contact
, een Model.List
voor dat type model wordt automatisch gemaakt. We kunnen dit gecreëerd uitbreiden Model.List
om helperfuncties toe te voegen die werken op een lijst met modelinstanties.
Contactlijst
heeft twee hulpfuncties nodig om een lijst met contacten te filteren en te rapporteren hoeveel contactpersonen er in elke categorie zijn. Voeg dit toe aan contacts.js
onmiddellijk na de Contact
model:
Contact.List = can.Model.List (filter: function (category) this.attr ('length'); var contacts = new Contact.List ([]); this.each (function (contact, i) if (category === 'all' || category === contact.attr ('category')) contacts.push (contact)) terug contacten;, tel: functie (categorie) retourneer dit.filter (categorie) .length;);
De twee hulpfuncties hier zijn:
filter()
doorloopt elk contact in de lijst en geeft een nieuw antwoord Contactlijst
van contacten binnen een categorie. this.attr ( 'lengte')
is hier opgenomen, dus EJS zal live-binding instellen wanneer we deze helper gebruiken in een weergave.telling ()
retourneert het aantal contactpersonen in een categorie met behulp van de filter()
helperfunctie. Omdat this.attr ( 'lengte')
in filter()
, EJS zal live-binding instellen wanneer we deze helper gebruiken in een weergave. Gebruik als u een helper in EJS gebruikt
attr ()
op een lijst- of instantie-eigenschap om live binding in te stellen.
Vervolgens wijzigt u de contactsList.ejs
weergave om contacten te filteren op basis van de categorie-eigenschap in de hash. In de contactsList.ejs
weergave, wijzigt u de parameter die is doorgegeven aan de lijst()
helper aan contacts.filter (can.route.attr ( 'categorie'))
. Uw EJS-bestand zou er als volgt uit moeten zien:
Op regel twee, filter()
wordt aangeroepen met de huidige categorie uit can.route
. Omdat je het hebt gebruikt attr ()
in filter()
en verder can.route
, EJS stelt Live-binding in om uw gebruikersinterface opnieuw te renderen wanneer een van deze wijzigingen wordt gewijzigd.
Inmiddels zou duidelijk moeten zijn hoe krachtig live-binding is. Met een kleine aanpassing aan uw mening, wordt de gebruikersinterface van de app nu volledig gesynchroniseerd met niet alleen de lijst met contacten, maar ook met de categorie-eigenschap die in de route is gedefinieerd.
Contacten worden gefilterd wanneer de categorie-eigenschap in de hash wordt gewijzigd. Nu heb je een manier nodig om alle beschikbare categorieën op te sommen en de hash te veranderen.
Maak eerst een nieuwe weergave om een lijst met categorieën weer te geven. Sla deze code op als filterView.ejs
in uw keer bekeken
map:
Laten we een paar regels uit deze code bekijken en zien wat ze doen:
<% $.each(categories, function(i, category) %>
$ .each
doorloopt de categorieën en voert een callback uit voor elke categorie.
"><%= category.name %> (<%= contacts.count(category.data) %>
Elke link heeft een data-categorie
attribuut dat in het data-object van jQuery zal worden getrokken. Later is deze waarde toegankelijk via .data ( 'categorie')
op de label. De naam en het aantal contacten van de categorie worden gebruikt als de koppelingstest. Live binding is ingesteld op het aantal contacten omdat
telling ()
calls filter()
welke bevat this.attr ( 'lengte')
.
can.Control
Control bindt automatisch methoden die eruitzien als gebeurtenishandlers wanneer een instantie wordt gemaakt. Het eerste deel van de gebeurtenishandler is de selector en het tweede deel is de gebeurtenis waarnaar u wilt luisteren. De selector kan elke geldige CSS-selector zijn en de gebeurtenis kan elke willekeurige DOM-gebeurtenis of aangepaste gebeurtenis zijn. Dus een functie zoals 'een klik'
zal luisteren naar een klik op een willekeurige tag binnen het element van de controle.
Controle maakt gebruik van delegatie van gebeurtenissen, zodat u zich geen zorgen hoeft te maken over het opnieuw koppelen van gebeurtenishandlers wanneer de DOM verandert.
Maak de besturing waarmee categorieën worden beheerd door deze code toe te voegen aan contacts.js
direct na de Contacten
Controle:
Filter = can.Control (init: function () var category = can.route.attr ('category') || "all"; this.element.html (can.view ('filterView', contacts: this .options.contacts, categories: this.options.categories)); this.element.find ('[data-categorie = "' + categorie + '"]') parent (). addClass ('actief'); , '[data-categorie] klik': functie (el, ev) this.element.find ('[data-categorie]'). parent (). removeClass ('active'); el.parent (). addClass ('actief'); can.route.attr ('categorie', el.data ('categorie')););
Laten we de code bekijken van het 'Filter' besturingselement dat u zojuist hebt gemaakt:
this.element.html (can.view ('filterView', contacts: this.options.contacts, categories: this.options.categories));
Zoals in de Contacten
Controle, in het()
toepassingen kan zien()
om categorieën en weer te geven html ()
om het in te voegen in het element van de Control.
this.element.find ('[data-categorie = "' + categorie + '"]') parent (). addClass ('actief');
Zoekt de koppeling die overeenkomt met de huidige categorie en voegt een klasse van 'actief' toe aan het bovenliggende element.
'[data-categorie] klik': functie (el, ev)
Luistert naar a Klik
gebeurtenis op elk element dat overeenkomt met de selector [Data-categorie]
.
. This.element.find ([data-categorie]) ouder () removeClass ( 'actief').; . El.parent () addClass ( 'actief');
Verwijdert de 'actieve' klasse uit alle links en voegt een klasse van 'actief' toe aan de link waarop is geklikt.
can.route.attr ('categorie', el.data ('categorie'));
Hiermee wordt de categorie-eigenschap bijgewerkt in can.route
de waarde uit het data-object van jQuery gebruiken voor de waarop is geklikt.
Net als de Contacten
Controle in deel een, je moet een nieuw exemplaar van de Filter
Controle. Werk uw documentklare functie bij om er als volgt uit te zien:
$ (document) .ready (function () $ .when (Category.findAll (), Contact.findAll ()). then (function (categoryResponse, contactResponse) var categories = categoryResponse [0], contacts = contactResponse [0 ]; nieuwe Contacten ('# contacten', contacten: contacten, categorieën: categorieën); nieuw Filter ('# filter', contacten: contacten, categorieën: categorieën););)
Met deze wijziging wordt een instantie van de Filter
Controle zal worden gemaakt op de #filter
element. Het wordt de lijst met contactpersonen en categorieën doorgegeven.
Wanneer u nu uw toepassing in een browser uitvoert, kunt u contactpersonen filteren door op de categorieën aan de rechterkant te klikken:
Dat is alles voor deel twee! Dit is wat we hebben bereikt:
In deel drie, zult u uw bestaande besturingselementen bijwerken zodat contacten kunnen worden bewerkt en verwijderd. Je zult ook een nieuwe controle en weergave maken waarmee je nieuwe contacten kunt toevoegen.
Kan niet wachten om meer te leren? Deel drie van de serie is hier geplaatst!