IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 2 - AngularJS filtry&moduly

V minulé lekci, Úvod do AngularJS, jsme se uvedli do AngularJS a dozvěděli se, jak je lehké naprogramovat webovou aplikaci v tomto jazyce.

Dnes si povíme něco o tom, jak filtrovat výstup v naší šabloně HTML a také jak vytvořit takový vlastní filtr.

V AngularJS můžeme filtrovat buďto repeatery (tedy direktivu ngRepeat) nebo samotné hodnoty a to nejen v šabloně, ale třeba i v controlleru nebo vlastní direktivě. Základní použití filtru v šabloně je následující.

{{ hodnota | filtr:parametr1:parametr2 | dalsiFiltr:parametr1 }}

Takto můžeme zavolat filter v JavaScruiptu. Proměnná $filter je servis předaný třeba controlleru, direktivě nebo něčemu jinému. Podobně jako u $scope tuto hodnotu sami nepředáváme. O to se postará DI subsystém angularu.

$filter(jméno);

$filter vrací většinou funkci, takže můžeme hned filtr zavolat např. $filter(jméno)(parametr1, parametr2)

Filtrování repeaterů

Filtrování repeaterů jsme si v rychlosti ukázali v minulém tutorálu. Teď si ho rozebereme trochu podrobněji. Framework nám nabízí pár vestavěných filtrů. Jsou jimi orderBy, filter a limitTo.

$filter('filter')(po­le, výraz) - filter:výraz

Filtr filer očekává jediný parametr. Je jím hodnota podle které se má výsledek filtrovat. Zobrazí se pak jen položky, které odpovídají danému filtru. Mějme třeba pole uživatel, ve kterém budou všichni uživatelé Devbooku. Pokud bychom chtěli udělat označení členů s automatickým dokončováním, bylo by velmi nepraktické pod inputem zobrazit celý seznam těchto uživatel. Právě tento seznam odfiltrujeme textem, který je v inputu, a tak pokud návštěvník zadá 'sd', zobrazí se mu jen uživatelé, kteří mají ve svém nicku výraz 'sd'.

Parametry

  • Pole - pole které chceme filtrovat
  • Výraz - {textový řetězec|objek­t|funkce} - výraz podle kterého budeme pole filtrovat
  • - textový řetězec: v poli zůstanou jen položky, které obsahují daný výraz. Všechny tyto položky budou vráceny samotným filterm jako nové pole
  • - objekt: Objekt můžeme použít, abychom filtrovali jen specifické oblasti pole. Pokud pole obsahuje objekty s více hodnotami (např. nick, web, telefon atp.), můžeme repeater filtrovat jen podle některé z nich nebo podle každé s jinými hodnotami. Např. výraz { nick: "sd", web: "devbook" } by se pojil se všemi uživateli v poli s nickem obsahujícím 'sd' a webovou stránkou obsahující 'devbook'. Název vlastnosti objektu (web, nick) můžeme nahradit znakem $ (dolar), který se pojí se všemi vlastnostmi objektu. Výraz { $: "sd" } má stejný efekt, jako výše uvedený příklad (tedy jen 'sd').
  • - funkce: pokud repeateru předáme funkci, bude zavolána pro každý element s určitými parametry. Filtr v tomto případě vrátí všechny prvky, u kterých funkce vrátila logickou hodnotu true

Příklad

<!DOCTYPE html>
<html ng-app>
    <head>
        <meta charset="utf8" />
        <script src="http://code.angularjs.org/angular-1.0.1.min.js"></script>
    </head>
    <body>
        <div ng-init="uzivatele = [{jmeno:'John', prijmeni:'Doe', email:'[email protected]'},
                                    {jmeno:'Jane', prijmeni:'Doe', email:'[email protected]'},
                                    {jmeno:'Joe', prijmeni:'Blow', email:'[email protected]'},
                                    {jmeno:'Chan', prijmeni:'Siu Ming', email:'[email protected]'}]"></div>

        Hledání: <input ng-model="searchText" />
        <table>
            <tr> <th>Jméno</th><th>Příjmení</th><th>E-mail</th> <tr>
            <tr ng-repeat="uzivatel in uzivatele | filter:searchText">
                <td>{{uzivatel.jmeno}}</td>
                <td>{{uzivatel.prijmeni}}</td>
                <td>{{uzivatel.email}}</td>
            <tr>
        </table><hr />

        Vše: <input ng-model="search.$" /> <br />
        Jen jméno <input ng-model="search.jmeno" /><br />
        Jen příjmení <input ng-model="search.prijmeni" /><br />
        Jen e-mail <input ng-model="search.email" /><br />
        <table>
            <tr> <th>Jméno</th><th>Příjmení</th><th>E-mail</th> <tr>
            <tr ng-repeat="uzivatel in uzivatele | filter:search">
                <td>{{uzivatel.jmeno}}</td>
                <td>{{uzivatel.pijmeni}}</td>
                <td>{{uzivatel.email}}</td>
            <tr>
        </table>
    </body>
</html>

Podobný příklad najdete i v oficiální API dokumentaci AngularJS

$filter('order­By')(pole, výraz[, převrátit]) - orderBy:výraz[:pře­vrátit]

Název tohoto filtru mluví za vše. Tento filtr pole seřadí podle zadaných hodnot. Ty jsou dvě. Jednak výraz, podle kterého chceme pole seřadit a pak jestli chceme pole seřadit vzestupně nebo sestupně.

Parametry

  • Pole - pole které chceme seřadit
  • Výraz - {funkce|textový řetězec|pole funkcí, textových řetězců} - výraz podle kterého budeme pole řadit
  • - funkce: Zavolá se pro každý prvek pole. Výsledek se bude řadit podle výstupu operátory < (menší než), = (rovno), > (větší než)
  • - textový řetězec: AngularJS váraz, který se shoduje s názvy vlastností objektu v poli (např. nick, web, telefon). Lze použít prefix + nebo - pokud chcete pole seřadit vzestupně (+) nebo sestupně (-)
  • - pole: Pole funkcí nebo textových řetězců. První z hodnot je použita vždy. Pokud jsou v poli dvě stejné hodnoty, je použita další položka tohoto pole k seřazení.
  • Převrátit - {logická hodnota} - převrátí výsledek

Příklad

<!DOCTYPE html>
<html ng-app>
    <head>
        <meta charset="utf8" />
        <script src="http://code.angularjs.org/angular-1.0.1.min.js"></script>
    </head>
    <body>
        <div ng-init="uzivatele = [{jmeno:'John', prijmeni:'Doe', email:'[email protected]'},
                                    {jmeno:'Jane', prijmeni:'Doe', email:'[email protected]'},
                                    {jmeno:'Joe', prijmeni:'Blow', email:'[email protected]'},
                                    {jmeno:'Chan', prijmeni:'Siu Ming', email:'[email protected]'}]">
            <pre>Řadit podle = {{predicate}}; převrátit = {{reverse}}</pre>
            <hr/>
            [ <a href="" ng-click="predicate=''">neseřazeno</a> ]
            <table>
                <tr>
                    <th><a href="" ng-click="predicate = 'jmeno'; reverse=false">Jméno</a>
                        (<a href ng-click="predicate = '-jmeno'; reverse=false">^</a>)</th>
                    <th><a href="" ng-click="predicate = 'prijmeni'; reverse=!reverse">Příjmení</a></th>
                    <th><a href="" ng-click="predicate = 'email'; reverse=!reverse">E-mail</a></th>
                <tr>
                <tr ng-repeat="uzivatel in uzivatele | orderBy:predicate:reverse">
                    <td>{{uzivatel.jmeno}}</td>
                    <td>{{uzivatel.prijmeni}}</td>
                    <td>{{uzivatel.email}}</td>
                <tr>
            </table>
        </div>
    </body>
</html>

$filter('limit­To')(pole, výraz) - limitTo:výraz

Filtr limitTo omezí repeater jen na daný počet výpisů od začátku pole. Ve výrazu může být číslo. Pokud uvedeme záporné číslo, budou se brát položky od konce daného pole.

Příklad

<!DOCTYPE html>
<html ng-app>
    <head>
        <meta charset="utf8" />
        <script src="http://code.angularjs.org/angular-1.0.1.min.js"></script>
    </head>
    <body>
        <div ng-init="uzivatele = [1,2,3,4,5,6,7,8,9,10]; limit = 3;">
            Limit {{uzivatele}}: <input type="text" ng-model="limit" /><br />
            Výstup: {{uzivatele | limitTo:limit }}
        </div>
    </body>
</html>

Filtrování hodnot

Dále můžete filtrovat hodnoty. V AngularJS je pár vestavěných filtrů uvedených v seznamu pod tímto odstavcem. Filtry lze volat v JS ze servisu $filter nebo v šabloně klasickým zápisem filtrů. Obecný zápis obou těchto způsobů je uveden výše.

  • currency: Zformátuje číslo jako měnu a vloží před něj symbol, který očekává v parametru. Zformátování čísla by tedy mohlo vypadat následovně:
{{ 1235 | currency['$'] }}

Výsledek: $1,235.00

  • date: Zformátuje timestamp nebo datum na zadaný formát data a času. Jako jediný parametr očekává formát, do kterého má timestamp zformátovat. Přehled najdete na adrese http://docs.angularjs.org/….filter:date Příklad použití filtru date:
{{ 1288323623006 | 'dd.M.yyyy H:m:s' }}

Výsledek: 29.10.2010 05:40:23

  • json: Zformátuje JavaScriptový objekt jako řetězec textu JSON. Příklad:
{{ { nick: "someone" } | json }}

Výsledek:

{
   "nick": "someone"
}
  • lowercase, uppercase: První převede text na malé znaky, druhý na velké.
{{ "DEVBOOK" | lowercase }}
{{ "devbook" | uppercase }}

Výsledek: devbook DEVBOOK

  • number: Zformátuje číslo. Jako parametr očekává číslo (počet desetinných míst, která má zobrazit)
{{ 1234.56789 | number:2 }}

Výsledek: 1,234.56

Tak to byly všechny základní předdefinované filtry v AngularJS. Někdy se může stát, že potřebujeme výstup (repeater nebo hodnotu) filtrovat jinak. V takové případě nám AngularJS nabízí vytvořit filtr vlastní. Jeden takový filtr, který bývá často potřeba, je filtr na zkracování textu. Pokud ale chceme definovat vlastní filtry, musíme si nejprve říct něco o modulech.

Moduly

Moduly sdružují filtry, direktivy a kontrolery, které patří k sobě. Dají se chápat jako takové namespace pro aplikaci. Moduly vytváří angular.module(jméno, vyžadované, konfigurační_fce). V parametrech je jméno modulu, což je textový řetězec, pole vyžadovaných modulů (jejich jmen - textových řetězců), které patří do tohoto modulu a které budeme v aplikaci používat. Poslední parametr je konfigurační funkce, o které si povíme víc v jiném díle seriálu. V parametrech je nepovinná.

Takže jak to souvisí s filtry? Je to prosté, filtr musí patřit do nějakého modulu, proto ho nejdřív musíme vytvořit. V externím JS souboru si tedy vytvoříme hlavní modul naší aplikace, který nazveme třeba testApp. Jméno hlavního modulu nesmíme zapomenout uvést v direktivě ngApp. Samotný modul ale ponecháme prázdný. V druhém parametru mu poze předáme jméno našeho druhého modulu testApp.filtry, kam vložíme náš filtr. Samotný filtr pak vytvoří module.filter, který má dva parametry, jméno filtru a továrnu, která musí vrátit modifikační funkci. Kód samotného filtru je pak velmi krátký a velmi užitečný, jak je zvykem v AngularJS. Filtr a zápis modulů by mohl vypadat například takto:

// Hlavní modul aplikace
angular.module('testApp', ['testApp.filtry']);

// Modul pro filtry
angular.module('testApp.filtry', [])
    .filter('truncate', function() {
        return function(text, delka, znaky) {

            // Pokud nedostaneme textový řetězec, nebudeme dělat nic
            if (!angular.isString(text)) return;

            // Vstupní parametry
            if (!angular.isNumber(delka))
                delka = 15;
            if (!angular.isString(znaky))
                znaky = "...";

            // Pokud je délka textu menší než délka v parametru, neprovedeme žádnou změnu
            if (text.length <= delka)
                return text;
            // Jinak text zkrátíme a přidáme za něj dané znaky
            return text.substring(0, delka) + znaky;
        };
    });

Všimněte si také, že AngularJS obsahuje funkce na kontrolu typů. Můžete samozřejmě použít operátor typeof, nicméně způsob angularu je čitelnější a nemusíte už nic vymýšlet. Nakonec nezapomeňte přidat do ngApp jméno hlavního modulu testApp a pak již můžete používat filtr truncate.

<!DOCTYPE html>
<html ng-app="testApp">
    <head>
        <meta charset="utf8" />
        <script src="http://code.angularjs.org/angular-1.0.1.min.js"></script>
        <script src="js/scripts.js"></script>
    </head>
    <body>
        <section>
            Textový řetězec: <input type="text" ng-model="text" /><br />
            <h4>Výstup po 25 znaků:</h4>
            <p>{{text|truncate:25}}</p>
            <h4>Výstup po 10 znaků:</h4>
            <p>{{text|truncate:10}}</p>
            <h4>Výstup po 5 znaků s ukončením ' =>':</h4>
            <p>{{text|truncate:5:' =>'}}</p>
        </section>
    </body>
</html>

V další lekci, První aplikace v AngularJS, si řekneme něco o direktivách a jak takovou vlastní direktivu vytvořit.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 543x (991 B)
Aplikace je včetně zdrojových kódů v jazyce JavaScript

 

Předchozí článek
Úvod do AngularJS
Všechny články v sekci
AngularJS
Přeskočit článek
(nedoporučujeme)
První aplikace v AngularJS
Článek pro vás napsal Drahomír Hanák
Avatar
Uživatelské hodnocení:
4 hlasů
Autor v současné době studuje Informatiku. Zajímá se o programování, matematiku a grafiku.
Aktivity