UBB Generator Part 2: De UI, Angular

Door Webgnome op zondag 27 december 2015 01:00 - Reacties (5)
Categorie: UBB Generator, Views: 1.421

Deel tweein de serie over de totstandkoming van de UBB generator focus ik mij vooral op de UI kant van het verhaal en dan met name Angular.

Ik heb gekozen om gebruik te maken van Angular Material omdat ik zelf geen graficus ben (of UX designer zoals dat tegenwoordig mooi heet) en toch iets representatiefs wilde neerzetten. Zelf ben ik wel fan van het Material design principe dus vandaar deze keuze. Angular Material komt met en groot aantal standaard directives die het mogelijk maken om snel een UI in elkaar te zetten.

Zoals aangegeven is de AppCtrl controller de controller die de zoekbalk en het tonen van de juiste 'card' aanstuurt. De manier waarop dat dit gebeurt is door gebruik te maken van zgn. $watch functies. Een $watch functie kun je op de $scope toevoegen om te zorgen dat bepaalde variabelen in de gaten worden gehouden. Je dient een functie te schrijven die twee paremeters bevat. Ik noem ze eigenlijk altijd n en o (new/old). Omdat deze $watch altijd minimaal één keer wordt afgetrapt dien je te controleren of dat de variabelen hetzelfde zijn (bij de eerste keer zijn de variabelen namelijk altijd beide 'null' ) en als dit niet het geval is dan kun je dingen gaan doen.

Voorbeeld van een dergelijke $watch is in het in de gaten houden welke service er gebruikt moet worden door de zoekbalk:


JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$scope.$watch('searchType',function(n,o){
        switch(n){
        case 'series':
            $scope.service= seriesService;
            $scope.searchPlaceholder = "Search a serie by title or IMDB id (tt..)";
            break;
        default:
            $scope.service = movieService;
            $scope.searchPlaceholder = "Search a movie by title or IMDB id (tt..)";
        }
        
        $scope.searchText = '';
        
    });



In dit voorbeeld controleer ik of de nieuwe waarde series is en zo niet dan wordt er een andere service op de scope gezet en de placeholder tekst voor de zoekbalk aangepast. Ik ben zelf wel gecharmeerd van deze manier van aanpak. Zo kun je in de controllers met een paar regels code functionaliteit schrijven die veranderd als je scope variabelen veranderen.

Directives

Op een bepaald moeten in de ontwikkeling ben ik begonnen met het gebruik van Directives. Directives zijn kleine stukken code / HTML die een bepaald onderdeel van je applicatie bevatten. De manier waarop ik de directives gebruik is door simpelweg zgn. partials in te laden op het moment dat ik het nodig heb.

Zo zijn er naast de material directives een ubbcard directive en een moviecard directive. Er zit hier niet heel veel spannends in behalve dan dat de controller in een andere angular module staat dan de directive. Dit wil ik in de toekomst nog aanpassen.

Services

Zoals gezegd maak ik gebruik van een aantal factories. De reden waarom ik een factory en geen service gebruik is omdat ik gelezen heb in de documentatie dat wanneer je een service maakt er iedere keer een nieuwe instantie gemaakt wordt je van je object en je dan ook in de knoop kan komen met caching. Dit heb ik zelf niet getest dat staat nog op het todo lijstje.

De manier waarop ik mijn factories maak is als volgt:


JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
services.factory('posterService',['$http','$q',function($http,$q){
    var s = {};
    s.cache = null;
    s.baseUrl = "api.php/posters";
    
    s.getPosters = function(){
        var def  = $q.defer();
        if(this.cache == null){
            $http.get(this.baseUrl).then(function(data){
                this.cache = data.data;
                def.resolve(this.cache);
            },function(data){
                def.reject(data);
            });
            return def.promise;
        }else{
            def.resolve(this.cache);
        }
        
    }
    return s;
}
]);



Om te beginnen definiëren we natuurlijk de factory door het een naampje te geven en de nodige dependencies. Het eerst volgende dat in de functie gebeurt is een leeg 'object' aan te maken waar ik vervolgens alle properties aan toevoeg. Dit vond ik zelf een leesbare manier van objecten opzetten in javascript. Als laatste stap return ik deze s.

Zo kan ik in mijn controllers dus simpelweg service.getPosters() afroepen en de nodige dingen doen. Zoals je ziet maak ik ook gebruik van $q. $q kan gebruikt worden om de promise die $http genereert door te gooien en zodoende in de call van $http nog wat dingen te doen voordat je de promise door geeft. Het voordeel hiervan is is dat je in de service laag de return waarde van $http kan manipuleren voordat je deze de controller in schiet. In de controller kun je dan nog steeds met service.doStuff().then(function(){},function(){}); blijven werken.

Een voorbeeld hiervan zou kunnen zijn dat je de data die je binnen krijgt wilt verrijken met data uit een andere call. Vervolgens als die laatste call goed gaat geef je de $q.defer() terug.

Volgende: UBB Generator Part 3: De backend. OMDB Api en Slim Framework 12-'15 UBB Generator Part 3: De backend. OMDB Api en Slim Framework
Volgende: UBB Generator Part 1: De Architectuur 12-'15 UBB Generator Part 1: De Architectuur

Reacties


Door Tweakers user Diumelia, maandag 28 december 2015 14:54

Ik vraag me af waarom je resources verspilt door het gebruik van $watch voor de 'searchType' variabele?! Op elke scope variabele zit al een watch, dus waarom nog één extra aanmaken en de digest loop extra complex maken?

Maak gebruik van de ngChange directive. Bijkomend voordeel hiervan is dat deze enkel getriggered wordt indien de user op de switch klikt en je zo de check of beide variabelen null zijn kan weglaten.

[Reactie gewijzigd op maandag 28 december 2015 14:54]


Door Tweakers user Gropah, maandag 28 december 2015 17:07

Ik kan je trouwens ook aanraden om eens te kijken naar Yeoman. Die kan heel veel van het angular spul aan routes etc voor je genereren, waardoor het niet alleen makkelijker en minder fout gevoelig ook nog eens een betere structuur heeft.

Door Tweakers user Brantje, maandag 28 december 2015 17:36

Dat kan nog makkelijker dan hierboven:
ng-placeholder="{ 'Placholder 1': myVar === 'mystring', 'Placeholder 2': myVar ==='string'}"

Door Tweakers user Diumelia, maandag 28 december 2015 17:51

Brantje schreef op maandag 28 december 2015 @ 17:36:
Dat kan nog makkelijker dan hierboven:
ng-placeholder="{ 'Placholder 1': myVar === 'mystring', 'Placeholder 2': myVar ==='string'}"
Dit zou een mogelijkheid geweest zijn moest de placeholder het enigste zijn dat verandert, wat hier niet het geval is (ook de te gebruiken service). Bovendien is naar mijn weten de ngPlaceholder directive niet standaard.

Door Tweakers user Webgnome, maandag 28 december 2015 19:16

Diumelia schreef op maandag 28 december 2015 @ 14:54:
Ik vraag me af waarom je resources verspilt door het gebruik van $watch voor de 'searchType' variabele?! Op elke scope variabele zit al een watch, dus waarom nog één extra aanmaken en de digest loop extra complex maken?

Maak gebruik van de ngChange directive. Bijkomend voordeel hiervan is dat deze enkel getriggered wordt indien de user op de switch klikt en je zo de check of beide variabelen null zijn kan weglaten.
Waarom ik de $watch gebruik is simpelweg omdat ik de ng-change blijkbaar helemaal over het hoofd heb gezien. Ik zal er eens naar kijken. Bedankt voor de tip.
Gropah schreef op maandag 28 december 2015 @ 17:07:
Ik kan je trouwens ook aanraden om eens te kijken naar Yeoman. Die kan heel veel van het angular spul aan routes etc voor je genereren, waardoor het niet alleen makkelijker en minder fout gevoelig ook nog eens een betere structuur heeft.
zal is kijken. Maar op dit moment is het niet nodig om er een tooltje bij te gebruiken. Het is nog vrij overzichtelijk allemaal

Reageren is niet meer mogelijk