AngularJS - Podstawowe filtry

AngularJS – Podstawowe filtry

Podziel się ze znajomymi

Wpis ten będzie o podstawowych filtrach jakie ma do zaoferowania AgnularJS. Służą one do zmiany wyświetlanych danych bez ich modyfikacji: filtrowania, sortowania czy formatowania danych. Jak już wspomniałem, opisywany framework dostarcza nam podstawowe filtry operujące na:

  • łańcuchach znaków,
  • liczbach,
  • datach,
  • obiektach JSON,
  • dyrektywie ng-repeat.

Część teoretyczna

Pokrótce omówię, każdy z typów na jakich mogą operować podstawowe filtry w AngularJS. Każdy filtr można wykorzystywać w kodzie HTML, jak również w kodzie JS. Filtry działają w taki sam sposób, a jedyna różnica jest w sposobie ich użycia. Dodatkowo niektóre z nich przyjmują parametry np. zaokrąglając liczbę, mamy możliwość określenia do ilu miejsc po przecinku dana liczba ma zostać zaokrąglona.

Dla HTMLa użycie filtra wygląda tak:

{{zmienna | filtr: parametr}}

Zaś dla kodu JS:

$filter('nazwa_filtru')(zmienna, parametr)

Łańcuch znaków

Mamy możliwość zamienienia wielkości liter za pomocą filtrów:

  • lowercase – odpowiada za formatowanie liter na małe,
  • uppercase – odpowiada za formatowanie liter na duże.

W kodzie HTML użycie tych filtrów wygląda następująco:

<p>{{ipnut | lowercase}}</p>
<p>{{ipnut | uppercase}}</p>

Dla JS wykorzystanie tego filtru wygląda nieco inaczej:

$filter('lowercase')(input)
$filter('uppercase')(input)

Liczby

Mamy również możliwość wykonywania operacji na liczbach. Dostępne filtry:

  • number – przybliża liczbę, jako parametr przyjmuje ilość miejsc po przecinku, w przypadku gdy brak parametru, przybliża do 3 miejsc po przecinku,
  • currency – liczba formatowana jest na walutę, jako parametr przyjmuje symbol lub identyfikator waluty. Gdy brak parametru przyjmuje lokalną walutę.

Przykład użycia w kodzie HTML

<p>{{ipnut | number}}</p>
<p>{{ipnut | number: 5}}</p>
<p>{{ipnut | currency: '€'}}</p>

Przykład użycia w kodzie JS

$filter('number')(ipnut)
$filter('number')(ipnut , 5)
$filter('currency')(ipnut, '€')

Data

Pisząc aplikację często zdarza się potrzeba wyświetlenia daty. Jednak nie zawsze jest to proste do wykonania. Za pomocą filtru date, wyświetlanie daty w odpowiednim formacie już nie będzie problemem.

Filtr date przyjmuje jako parametr słowa określające rodzaj wyświetlanej daty:

  • medium – 29 marca 2018 20:51:24,
  • short – 29 marca 2018 20:51,
  • fullDate – czwartek, 29 marca 2018,
  • longDate – 29 marca 2018,
  • mediumDate – 29 mar 2018,
  • shortDate – 29.03.2018,
  • mediumTime – 20:51:24,
  • shortTime -20:51.

Dodatkowo możemy również sami tworzyć własne typy wyświetlanych dat, używając znaków kluczowych odpowiadających odpowiednim danym:

  • Czterocyfrowy rok: ‚yyyy’ – 2018,
  • Dwucyfrowy rok: ‚yy’ – 18,
  • Miesiąc słownie: ‚MMMM’ – marca,
  • Miesiąc słowny skrót: ‚MMM’ – mar.,
  • Dwucyfrowy miesiąc: ‚MM’ – 03,
  • Miesiąc: ‚M’ – 3,
  • Dwucyfrowy dzień: ‚dd’ – 02,
  • Dzień: ‚d’ – 2,
  • Dzień tygodnia słownie: ‚EEEE’ – czwartek,
  • Dzień tygodnia skrót: ‚EEE’ – czw.,
  • Dwucyfrowa godzina (0-23): ‚HH’ – 04,
  • Godzina (0-23): ‚H’ – 4,
  • Dwucyfrowa godzina (01-12): ‚hh’ – 04,
  • Godzina (01-12): ‚h’ – 4,
  • Dwucyfrowa minuta: ‚mm’ – 06,
  • Minuta: ‚m’ – 6,
  • Dwucyfrowa sekunda: ‚ss’ – 09,
  • Sekunda: ‚s’ – 9,
  • Milisekunda z kropką: ‚.sss’ – .400,
  • Milisekunda z przecinkiem: ‚,sss’ – ,400.

Przykład użycia w kodzie HTML

<p>{{ipnut | date: 'dd-MM-yyyy'}}</p>
<p>{{ipnut | date: 'yyyy-MM-dd'}}</p>
<p>{{ipnut | date: 'yy-MM-dd'}}</p>

Przykład użycia w kodzie JS

$filter('date')(ipnut , 'dd-MM-yyyy')
$filter('date')(ipnut , 'yyyy-MM-dd')
$filter('date')(ipnut , 'yy-MM-dd')

JSON

Wyświetlanie obiektu JS na stronie umożliwia nam filtr json.

Przykład użycia w kodzie HTML

{{ obiekt | json }}

Przykład użycia w kodzie JS

$filter('json')(obiekt)

Dyrektywa ng-repeat

Wyświetlane tablice mogą być filtrowane na kilka sposobów:

  • sortowane,
  • ograniczane limitem,
  • przeszukiwane.

Sortowanie

Odbywa się za pomocą filtra orderBy. Sortowanie może być zarówno rosnące (+) jak i malejące (-).

Przykład użycia w kodzie HTML

tablica | orderBy: ['kierunek pole']

Przykład użycia w kodzie JS

$filter('orderBy')(tablica, pole kierunek)

Ograniczenie limitem

Czasem nie chcemy wyświetlać całej zawartości tabeli w naszej aplikacji, a jedynie wybraną część, wtedy z pomocą przychodzi filtr limitTo, który to jako parametr przyjmuje ilość wyświetlanych danych.

Przykład użycia w kodzie HTML

tablica | limitTo: limit

Przykład użycia w kodzie JS

$filter('limitTo')(tablica, limit)

Przeszukiwanie

Często na stronach internetowych mamy mechanizm wyszukiwania, który po wprowadzeniu każdej literki zawęża wyniki. Taki efekt możemy uzyskać za pomocą filter, który jako parametr przyjmuje obiekt.

Przykład użycia w kodzie HTML

tablica | filter: {'atrybut':'wartość'}

Przykład użycia w kodzie JS

$filter('filter')(tablica, {'atrybut':'wartość'})

Przykładowa aplikacja

Aplikacja będzie bardzo prosta w działaniu. Będziemy mieli przyciski, które będą określać rodzaj filtrowanych danych, pole do wprowadzania danych oraz wyniki uzyskane poprzez zastosowanie podstawowych filtrów.

Plik index.html

<!DOCTYPE html>
<html lang="pl" ng-app="app">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>AngularJS #11</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
        crossorigin="anonymous">

    <style>
        .panel-default {
            margin-top: 2em;
            padding: 1em;
        }

        .btn {
            margin-bottom: 2em;
        }

        .control-form {
            width: 100%
        }

        .inupt-text {
            margin-bottom: 1em;
            width: 100%;
        }

        .error {
            color: red;
        }
    </style>

</head>

<body ng-controller="appController as appCtrl">

    <div class="row">
        <div class="col-md-4 col-md-offset-4 panel panel-default">
            <choose-type-component data="appCtrl.data"></choose-type-component>
            <input-component data="appCtrl.data"></input-component>
            <output-component data="appCtrl.data"></output-component>
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.2.1.slim.js" integrity="sha256-tA8y0XqiwnpwmOIl3SGAcFl2RvxHjA8qp0+1uCGmRmg="
        crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
        crossorigin="anonymous"></script>

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>

    <script>
        var app = angular.module("app", []);

        app.controller('appController', function () {
            var ctrl = this;
            ctrl.data = {
                type: 0,
                title: 'String'
            };
        });

        app.component('chooseTypeComponent', {
            templateUrl: 'chooseType.html',
            bindings: {
                data: '='
            },
            controller: chooseTypeController
        });

        app.component('inputComponent', {
            templateUrl: 'inputComponent.html',
            bindings: {
                data: '='
            },
        });

        app.component('outputComponent', {
            templateUrl: 'outputComponent.html',
            bindings: {
                data: '<'
            }
        });

        function chooseTypeController() {
            var ctrl = this;
            ctrl.changeType = function (type) {
                switch (type) {
                    case 'string':
                        ctrl.data.type = 0;
                        ctrl.data.ipnut = '';
                        ctrl.data.title = 'String';
                        break;
                    case 'number':
                        ctrl.data.type = 1;
                        ctrl.data.ipnut = '';
                        ctrl.data.title = 'Number';
                        break;
                    case 'date':
                        ctrl.data.type = 2;
                        ctrl.data.ipnut = new Date();
                        ctrl.data.title = 'Date';
                        break;
                    case 'json':
                        ctrl.data.type = 3;
                        ctrl.data.ipnut = '';
                        ctrl.data.title = 'JSON';
                        ctrl.data.json = {
                            'name': 'Avatar',
                            'year': '2009'
                        };
                        break;
                    case 'ngRepeat':
                        ctrl.data.type = 4;
                        ctrl.data.ipnut = '';
                        ctrl.data.title = 'ngRepeat';
                        ctrl.data.movies = [{
                            'name': 'Avatar',
                            'year': '2009'
                        }, {
                            'name': 'Shrek',
                            'year': '2001'
                        }, {
                            'name': 'Transporter',
                            'year': '2002'
                        }];
                        break;
                    default:
                        console.error('err');
                }
            };
        }
    </script>
</body>

</html>

Aplikacja wygląda podobnie do tych z poprzednich wpisów, dodatkowo została oparta na komponentach.

W części odpowiedzialnej za JS, tworzymy moduł aplikacji, a następnie przystępujemy do utworzenia kontrolera całej aplikacji. To ten kontroler będzie przechowywał wszystkie dane. Deklarujemy zmienną ctrl, następnie tworzymy obiekt data z dwoma polami: type ustawione na 0 oraz title mające w sobie tekst String.

chooseTypeComponent

Kolejnym krokiem jest utworzenie komponentu chooseTypeComponent, który ma określony szablon html w osobnym pliku chooseType.html, przekazaną dwukierunkowo daną date oraz określony komponent chooseTypeController.

Plik z szablonem zawiera w sobie 5 przycisków, których kliknięcie powoduje wykonanie się funkcji changeType() i przekazanie określonego parametru.

Kod pliku chooseType.html

<button class="btn btn-default" type="submit" ng-click="$ctrl.changeType('string')">String</button>
<button class="btn btn-default" type="submit" ng-click="$ctrl.changeType('number')">Number</button>
<button class="btn btn-default" type="submit" ng-click="$ctrl.changeType('date')">Date</button>
<button class="btn btn-default" type="submit" ng-click="$ctrl.changeType('json')">JSON</button>
<button class="btn btn-default" type="submit" ng-click="$ctrl.changeType('ngRepeat')">ngRepeat</button>

Przejdźmy teraz do omówienia tego co dzieje się w komponencie. Głównym zdaniem komponentu będzie utworzenie funkcji, która będzie wykonywana po przyciśnięciu danego przycisku. Zatem tworzymy zmienną ctrl, a następnie funkcję changeType(type), która przyjmuje parametr type, określający na jaki typ zmieniony zostaje „input” oraz „output” danych. Tworzony jest switch, który sprawdza parametr i na jego podstawie wykonuje odpowiednie operacje.

String
W przekazanym dwukierunkowo obiekcie date zmianie ulegają pola:

  • type, ustawione na 0,
  • ipnut, zostaje wyzerowany,
  • title, ustawiony na String.

Number
Zmienione pola:

  • type na 1,
  • input zostaje wyzerowany,
  • title, ustawiony na Number.

Data
Zmienione pola:

  • type zostaje ustawione na 2,
  • input zostaje zainicjalizowany obecną datą,
  • title zawiera napis Date.

JSON
Zmienione pola:

  • type ustawiony na 3,
  • input wyzerowany,
  • title ustawiony na słowo JSON,
  • dodatkowo utworzony nowy obiekt json, który jest filtrowany w pliku html.

ngRepeat
Zmienione pola:

  • type ustawiony na 4,
  • input wyzerowany,
  • title ustawiony na słowo ngRepeat,
  • dodatkowo zostaje utworzona tablica obiektów movie.

Wartość domyślna switcha wyświetla w konsoli błąd.

inputComponent

Kolejnym krokiem w naszej aplikacji jest utworzenie komponentu inputComponent, którego zadaniem jest wprowadzanie danych. WYstępuje tu dwukierunkowe przekazanie danych.

Kod html inputComponent.html

<h1 class="text-center">{{$ctrl.data.title}}</h1>
<div class="form-group">
    <input type="text" class="form-control" ng-model="$ctrl.data.ipnut" ng-if="!($ctrl.data.type === 3 || $ctrl.data.type === 4)">
</div>

Jak możemy zauważyć, pole wprowadzania danych dla typów 4 nie jest wyświetlane, ponieważ w tych typach filtrowane są inne dane.

outputComponent

Pozostało nam jeszcze utworzenie komponentu odpowiedzialnego za wyświetlanie filtrowanych danych. Tym zadaniem zajmuje się komponent outputComponent. Do którego, przekazywane są jednokierunkowo wszystkie dane.

Kod html outputComponent.html

<div ng-if="$ctrl.data.type === 0">
    <p>{{$ctrl.data.ipnut | uppercase}}</p>
    <p>{{$ctrl.data.ipnut | lowercase}}</p>
</div>
<div ng-if="$ctrl.data.type === 1">
    <p>{{$ctrl.data.ipnut | number}}</p>
    <p>{{$ctrl.data.ipnut | number: 5}}</p>
    <p>{{$ctrl.data.ipnut | currency: '€'}}</p>
</div>
<div ng-if="$ctrl.data.type === 2">
    <p>{{$ctrl.data.ipnut | date: 'dd-MM-yyyy'}}</p>
    <p>{{$ctrl.data.ipnut | date: 'yyyy-MM-dd'}}</p>
    <p>{{$ctrl.data.ipnut | date: 'yy-MM-dd'}}</p>
</div>
<div ng-if="$ctrl.data.type === 3">
    <p>{{$ctrl.data.json | json}}</p>
</div>
<div ng-if="$ctrl.data.type === 4">
    <h3>OrderBy</h3>
    <p ng-repeat="movie in $ctrl.data.movies | orderBy: ['-year']">
        <strong>Name: </strong>{{movie.name}} |
        <strong>year: </strong>{{movie.year}}</p>
    <p>...........</p>
    <p ng-repeat="movie in $ctrl.data.movies | orderBy: ['year']">
        <strong>Name: </strong>{{movie.name}} |
        <strong>year: </strong>{{movie.year}}</p>
    <h3>LimitTo</h3>
    <p ng-repeat="movie in $ctrl.data.movies | orderBy: ['year'] | limitTo: 1">
        <strong>Name: </strong>{{movie.name}} |
        <strong>year: </strong>{{movie.year}}</p>
    <h3>Filter</h3>
    <p ng-repeat="movie in $ctrl.data.movies | filter: {'year':'2009'}">
        <strong>Name: </strong>{{movie.name}} |
        <strong>year: </strong>{{movie.year}}</p>
</div>

Jak można zobaczyć w powyższym kodzie, zostały użyte wszystkie omówione w części teoretycznej filtry.

Efekt działania aplikacji

AngularJS - Podstawowe filtry - app

Podsumowanie

W tym wpisie opowiedziałem jakie możliwości dają nam podstawowe filtry oraz pokazałem jak używać ich w praktyce. Poprzez stworzenie prostej aplikacji mogliśmy zobaczyć jak działają oraz w jaki sposób wykorzystać możliwości jakie daje nam framework AngularJS.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *