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')(pole, 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|objekt|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 hodnotutrue
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('orderBy')(pole, výraz[, převrátit]) - orderBy:výraz[:převrá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('limitTo')(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 544x (991 B)
Aplikace je včetně zdrojových kódů v jazyce JavaScript