1/8 - SPA , AngularJS, Bootstrap - 2

 Legutóbb addig jutottunk el, hogy a navigációs sáv működött. Ezen a gyakorlaton hozzá fogunk adni egy UI komponenst, amely kezelni tudja a tutorial-okat. Első lépésben azt szeretnénk elérni, hogy megjelenjen néhány cím, amik között léptetni lehet.

Hozzuk létre ezeket a címeket a main.js-ben egy $scope változóbanm a setActivePage alá.


    $scope.setActivePage = function (page) {
        activePage = page;
    }

    $scope.tutorialTitles = [
        "Authentication",
        "Connecting ClientApp to an API",
        "Interacting with CosmosDB"
    ]
});

Ezután hozzunk létre egy mappát a public alatt az új komponensünknek, és benne 3 db fájlt


A tutorialsDirective.js tartalmazza a direktíva regisztrációját. Másoljuk be ebbe a fájlba a következőket.


app.directive('tutorialsPage'function(){
    var directive = {
        restrict: 'E',
        templateUrl: './tutorials/tutorials-view.html',
        scope:{
            tutorials: "=tutorialsin"
        },
        controller: 'tutorialsController'
    }
    return directive;
});

Az app az alkalmazásunkat jelöli. Mivel a scriptet tartalmazű fájlt a main.js fájl után fogjuk belinkelni, ezért az app változó már be lesz állítva. A 'tutorialsPage' a direktíva neve, az utána lévő függvény pedig létrehozza a direktívát a megfelelő paraméterek szerint.

  • restrict: 'E' - a direktíva egy HTML elemként fog megjelenni.
  • replace: true - a template-ben megadott html közvetlenül (wrapper/csomagoló elem nélkül) fog beillesztkedni
  • templateUrl: a beillesztendő HTML template (sablon) elérési útja az index.html-hez képest
  • scope: jelen esetben a bemenő paramétereket foglalja magában. a bal oldali érték megadja, hogyan hivatkozhatunk majd rá a controllerben, illetve a html fájlban (azaz a komponensen belül), a jobb oldali érték pedig azt adja meg (tutorialsin), hogyan adjuk majd át az adatokat a komponensnek.
  • controller: megadja a controllert, ami a komponensünk adatait vezérli majd.
A tutorialhoz tartozó sort az index.html-ben cseréljük ki az alábbiakra

  <div class="container-fluid" ng-show="isActive('tutorials')">
      <tutorials-page tutorialsin="tutorialTitles"></tutorials-page>
  </div>

A tutorialsin változót nem szükséges így hívni, azért adtam meg az "in" végőzédést, hogy lássuk hogyan van összekötve ez az egész. A HTML fájlban "tutorials-page"-ként kell a direktívát behivatkozni. Az elnevezés (tutorialsPage) úgy alakul át, hogy minde nagy betűnél egy '-' karakter kerül be, és az karakter kisbetűsre változik. Ez azért van, mert a HTML attribútumok nem tudják kezelni a kis-magybetű különbségeket. (pl ha tutorialsIn lenne a Javascriptben, akkor a html-ben tutorials-in-ként kellene behivatkozni)

A main.js-ben $scope-ra deklarált változót, a tutorialTitles-t itt kötjük be a tutorialsin-be, azaz bemenő paraméterként adjuk a komponensnek. Most pedig váltsunk át a tutorials-view.html-be.És adjuk meg az alábbi kódot.

<div class="align-center row">
    <button ng-disabled="!activeIndex" 
            ng-click="previous()" class="col btn btn-default">
        previous
    </button>
    <span class="col">{{activeTitle}}</span>
    <button ng-disabled="activeIndex === tutorials.length-1" 
            ng-click="next()" class="col btn btn-default">
        next
    </button>
</div>

Ez a felület abból áll, hogy léptetni tudunk majd balra és jobbra a tutorial-címek között. Ezért szükségünk lesz a controllerben egy previous és egy next függvényre, valamint számon kell tartanunk mi az aktuális tutorial indexe.

A tutorialsController.js tartalma így fog kinézni.



app.controller('tutorialsController'function ($scope) {

    $scope.activeTitle = $scope.tutorials && $scope.tutorials.length
        ? $scope.tutorials[0] : null;

    //Az aktuális tutorial indexe
    $scope.activeIndex = 0;

    //a previous gomb megnyomására
    $scope.previous = function () {
        if ($scope.tutorials && $scope.tutorials.length) {
            //ha nem az első, akkor kiválasztjuk az előző indexet
            $scope.activeIndex = $scope.activeIndex ? $scope.activeIndex - 1 : $scope.activeIndex;
            //beállítjuk a címet
            $scope.activeTitle = $scope.tutorials[$scope.activeIndex];
        }
    }

    $scope.next = function () {
        if ($scope.tutorials && $scope.tutorials.length) {
            //ha nem az utolsó, akkor kiválasztjuk a következő indexet
            var isNotLastIndex = (($scope.tutorials.length-1) - $scope.activeIndex);
            $scope.activeIndex =  isNotLastIndex ? $scope.activeIndex + 1 : $scope.activeIndex;
            $scope.activeTitle = $scope.tutorials[$scope.activeIndex];
        }
    }
});

Itt pár dolgot kihasználtam a javascript-ről, amit minden "menő" programozó alkalmaz. Például az Elvis operátort használtam ( ?: ) azért hívják így mert ha oldalról nézed, akkor olyan mint egy Elvis fej.


Na jó, egy kis képzelőerő kell hozzá. Az elvis operátor (unalmas nevén kérdőjel-kettőspont operátor) úgy működik, hogy a kérdőjel előtti értéket kiértékeli, hogy igaz-e, ha igaz, akkor a kérdőjel utáni részt adja vissza, ha pedig hamis, akkor a kettőspont utáni részt. 



$scope.activeIndex =  isNotLastIndex ? $scope.activeIndex + 1 : $scope.activeIndex;

Tehát beállítom az aktív indexet. Mire? Ha ez nem az utolsó index, akkor 1-gyel nagyobb értékre, ha pedig az utolsó, akkor a saját értékére.

A következő dolog amit kihasználtam, hogy a 0 érték hamisnak számít. Tehát ha az utolsó értéknél vagyunk, akkor 
(($scope.tutorials.length-1) - $scope.activeIndex);

Értéke 0 lesz. Mivel az utolsó index a tömbben length-1. Ezt mindenki tudja, és elfogadja, csak a Fortran programozók nem.


Indítsuk el az alkalmazást az npm start-tal, és böngészőben próbáljuk ki.


Remek. Most pedig tuningoljunk egy kicsit a desing oldalon.

Adjunk hozzá egy general.css fájlt az alábbi tartalommal a public folder alá, majd linkeljük be az index.html-be.

.align-center{
    text-aligncenter;
}

.line-height-3em{
    line-height3em;
}



Ezután pedig alakítsuk át a tutorials-view.html-t így.


A bootsrap grid rendszere hozzásegít, hogy szépen nézzen ki a felhasználói felületünk mobilon. Röviden arról van szó, hogy CSS osztályokkal megadsz sorokat és oszlopokat. Például a row-val definiálhatsz egy sort (Az oldal 100% szélességét kitevű elemet). Minden sor 12 oszlopból áll, és te oszthatod fel ezt az alatta "row" alatt lévő gyerek elemekre. Most úgy osztottuk fel, hogy 2-8-2 (16.67% - 66.67% - 16.67%), Az xs pedig azt jelenti, hogy ez kisméretű eszközökön fog érvényesülni.

Mivel azonban a bootstrap mobile-first (azaz ha alkalmazol egy osztály, akkor az mindaddig érvényben marad, amíg egy szélesebb eszközön felül nem definiálod), ezért ez az osztály nagyobb eszközökön is fog érvényesülni. Próbáljuk ki. Váltsunk Responziv nézetbe a böngészőben, ahogy azt az előző részben is csináltuk, és húzzuk kifelé a csúszkát.


Írjuk át most a col-os (olvasd kol-os, még véletlenül sem colos, nehogy erősítsük itt az angolszász mértékegység rendszer terjedését.) 

<div class="align-center row">
    <div ng-disabled="!activeIndex" ng-click="previous()" class="col-xs-12 col-md-2">
       back
    </div>
    <div class="col-xs-12 col-md-8 align-center line-height-3em">{{activeTitle}}</div>
    <div ng-disabled="activeIndex === tutorials.length-1" ng-click="next()" class="col-xs-12 col-md-2">
       next
    </div>
</div>

Így most a szélesebb eszközökön fog teljesülni, amit az előbb beállítottunk. A keskenyebb eszközökön viszont, egymás alá fog kerülni a gomb és a tartalom.


Most már csak néhány ikon kell, és küldhetik a milliókat nekünk. A bootstrapnak van saját ikonpakkja is. Innen lehet nézni egy pár ikont, például a bal és jobb oldali nyilaknak.



Annyi az egész, hogy kimásolod az svg-t és beteszed, a next és a previous helyére.




Tippek trükkök

  • Ha további ingyenes ikonokat szeretnél elérni javasolni tudom még a fontawesome library-t
    https://fontawesome.com/icons?d=gallery
  • Az AngularJS támogatása sajnos 2021 végén megszűnik, ezért új projektekre már nem ajánlják. Azért kezdtem ezzel, mert jól lehet rajta szemléltetni az adatkötést. A továbbiakban az új Angularral fogok demonstrálni.
  • Ha szeretnél értesülni a frissítésekről iratkozz fel jobb felül.
  • Ha bármi kérdésed van tedd fel az alábbi visszajelző formon anonym.

Nincsenek megjegyzések:

Megjegyzés küldése