Les 3: Single Page Applications
Les 3: Single Page Applications
Tijdens deze oefening voeg je een labeling systeem toe voor taken, voeg je een side-menu toe en implementeer je verschillende views voor de taken. Tijdens deze oefeningenreeks oefen je op:
- De leerstof van de vorige 2 lessen
- Services
- 2-way databinding
- Herbruiken van code
- Lezen en begrijpen van documentatie
Deze oefeningen bouwen verder op het lesvoorbeeld van les 3.
Oefening 1: 2-way databinding
Vorige oefeningenreeks heb je een filter gebouwd die gebruikt kon worden om, onder andere, enkel de afgewerkte taken te selecteren. Pas de code voor deze filter aan zodat 2-way-databinding gebruikt wordt in de plaats van event binding via het ionChange event.
Oefening 2: TaskPage titel
Momenteel toont de TaskPage altijd de titel "New Task" zorg dat deze aangepast wordt naar "Edit Task" als de pagina gebruikt wordt om een bestaande taak aan te passen.

Oefening 3: Label datatype
Voeg een datatype toe dat een label voorstelt. Een label kan van alles zijn: dringend, belangrijk, studie, werk, familie, hobby, … De gebruiker voegt zelf de nodige labels toe. Pas het Task datatype aan zodat er één of meer labels toegevoegd kunnen worden aan een taak
De interface Label bevat 3 velden, name, color en id. De kleuren worden in een enum gedefinieerd en zijn: primary, secondary, tertiary, success, warning, danger, light, medium en dark.
Bouw vervolgens een service waarmee labels toegevoegd, opgehaald en verwijderd kunnen worden. Gebruik onderstaande code om 3 test labels te initialiseren. Vergeet niet dat het verwijderen van een label betekent dat dit label ook van alle taken verwijdert moet worden. Voor deze opgave is het handig om te weten dat services in andere services geïnjecteerd kunnen worden.
this.#labels.push({name: 'Dringend', color: Color.danger, id: 0});
this.#labels.push({name: 'Studies', color: Color.primary, id: 1});
this.#labels.push({name: 'Werk', color: Color.secondary, id: 2});
Oefening 4: Labels toevoegen
Implementeer de functionaliteit om een label toe te voegen of te verwijderen via de TaskPage component. Het formulier op deze pagina toont een lijst van alle labels, elk label krijgt de gepaste kleur. Het is vanzelfsprekend dat deze wijzigingen bewaard worden en nog zichtbaar zijn als je terugkeert naar de HomePage component en daarna terug naar de TaskPage component navigeert voor diezelfde taak.

Voor deze opgave kan je gebruikmaken van de <ion-checkbox> component. Daarnaast is het waarschijnlijk ook handig om te weten dat je het *ngFor directive als volgt kan uitbreiden zodat het een index bevat.
<ion-item *ngFor='let label of labels; let i = index'>
<!-- Some code -->
</ion-item>
Oefening 5: Menu
Voeg een <ion-menu> toe aan de app. Het menu mag maar op één locatie binnen je app gedefinieerd worden. Plaats het dus in de app.component.html template. Zo controleert het menu de volledige app en staat het zelf niet binnen de <ion-router-outlet> component.
Waarschuwingen
De voorbeelden die in de documentatie staan voor V6 van Ionic zijn, voor de <ion-menu> component, niet heel duidelijke. Als je naar de documentatie voor V5 gaat kijken, vind je meer uitgebreide voorbeelden. Vergeet niet om terug te keren naar versie 6 voor het vervolg van de oefeningen.
Je menu moet 3 links bevatten. Maak voor de twee onderste nog een pagina aan.

Om het menu te openen kan je swipen, maar het is duidelijker wanneer het menu ook met een knop geopend kan worden. Voeg aan elke pagina (behalve de detailpagina van de taken) een <ion-menu-button> toe.
Het menu sluit zich nog niet nadat je op een link klikt. Dit is eenvoudig op te lossen. In de documentatie zie je onderaan een lijst van methodes staan. Om deze te gebruiken heb je een verwijzing naar het menu nodig, hiervoor kan je template variables gebruiken. In onderstaand fragment gebruiken we de template variable #menu, deze variabele kan via event binding gebruikt worden om de juist methode op te roepen bij een click event (de # moet hier niet vermeld worden).
<ion-menu side='start' menuId="side-menu" contentId='main'
#menu>
<!-- Rest van de code heb je eerder in de opgave geschreven-->
</ion-menu>
Oefening 6: Labels
De labels pagina toont de gebruiker een overzicht van de verschillende labels die aanwezig zijn in de app. De labels worden getoond in een lijst waar elk label de gepaste kleur krijgt.
Voeg opnieuw een FAB-button toe. Ditmaal opent deze geen nieuwe pagina, maar een <ion-modal> component (het modale scherm is een aparte component die nog aangemaakt moet worden). De lay-out van het modale venster gebruikt <ion-chip> componenten om de verschillende kleuren te tonen. Voor deze componenten wordt enkel de outline getoond, met uitzondering van de geselecteerde kleur, hier wordt het de component getoond met een achtergrond.

De lay-out in bovenstaand screenshot is opgebouwd met de <ion-grid>, <ion-row> en <ion-col> componenten. Deze componenten werken op dezelfde manier als de grid systemen in CSS-frameworks zoals Bootstrap, Materialize, Tailwind, … Tenslotte is CSS-code toegevoegd om de breedte van de <ion-chip> componenten en de <ion-labels> binnen een cell in het grid op 100% te zetten. Om de tekst te centreren zijn er Ionic utility klassen beschikbaar.
Om een nieuw label aan te maken heb je twee keuzes. De eerste en meest voor de hand liggende optie is om de LabelService rechtstreeks aan te spreken vanuit de modale component. Een tweede optie is om de onDismiss methode van een modaal venster te gebruiken. Binnen de presentModal methode (zie de documentatie), kan je via onDismiss een functie oproepen die de afhandeling doet. Dit is niet vereist, maar is wel een goede oefeningen. In de oplossingen wordt deze methode gebruikt.
modal.onDidDismiss().then(d => console.log('Not implemented yet.'));
Oefening 7: Taken per label
De laatste pagina toont per label alle taken die met dit label gemarkeerd zijn. Deze view begint met een volledig dichtgeklapt menu. Door op de hoofdingen te drukken kunnen de lijsten van taken geminimaliseerd of gemaximaliseerd worden. Je kan de <ion-accordion> component gebruiken om onderstaande lay-out na te bouwen.
Deze view ziet er anders uit dan de eerste, maar heeft wel 100% dezelfde functionaliteit. Taken moeten nog steeds aangemaakt, geüpdatet, en verwijderd kunnen worden. Ook de status moet gewijzigd kunnen worden. Je zult merken dat de routing in de gedeelde component nog niet werkt, deze is momenteel niet ingesteld om universeel te werken. Het pad is relatief gedefinieerd ten opzichte van de huidige locatie. Om de component in verschillende pagina’s te kunnen gebruiken moet dit aangepast worden naar een absoluut pad.