Snadnější směrování AngularJS pomocí Angular UI Router

Ačkoli je AngularJS dodáván s vestavěným směrováním, někdy se vám může zdát omezující; framework Angular UI Router vám může pomoci ulehčit. Nativní implementace směrování AngularJS je zodpovědná za inicializaci řadičů, které odpovídají trasám aplikace. Ačkoli tato funkce funguje dobře v základních scénářích, v pokročilých situacích rychle zjistíte, že nativní směrování Angularu:

  • Vyžaduje, abyste při změně adresy URL ručně měnili řetězce URL v celé bázi kódu.
  • Vyžaduje, abyste si doslovně pamatovali syntaxi trasy pro přechod na stránku.
  • Nabízí vnořené pohledy.
  • Nabízí pojmenované pohledy.
  • Neumožňuje předávat data během navigace.

Alternativou je framework Angular UI Router, který představuje abstrakční vrstvu pro směrování a nabízí deklarativnější přístup k navigaci. Framework UI Router také vyplňuje některé mezery nativní implementace tím, že poskytuje vnořené a pojmenované pohledy, umožňuje předávat data mezi pohledy a mnoho dalšího.

Rámec Angular UI Router je abstrakční vrstva pro směrování, která obsahuje deklarativní přístup k navigaci

V tomto článku se naučíte vytvořit jednoduchou aplikaci, která využívá rámec UI Router. Cestou se seznámíte se stavy, s tím, jak řešit závislosti, a naučíte se různé metody navigace.

Poznání stavů

Snad nejlépe oceníte problém, který chce framework UI Router vyřešit, když se zamyslíte nad povahou webu. Ve většině aplikací při vytváření odkazu na stránku definujete explicitní cestu URL. Pokud byste například chtěli přejít na stránku Produkty vašeho webu, můžete mít adresu URL například takto:

Ukázka kódu 1: Flexibilní kontejner verze 2

http://www.example.com/products

V této situaci jsou dva problémy. První spočívá v tom, že si při každém vytvoření odkazu musíte pamatovat přesnou doslovnou cestu ke stránce Produkty. I když si zde uvedený příklad lze snadno zapamatovat, mnoho reálných adres URL si tak snadno zapamatovat nelze. Na další problém narazíte, když se stane nevyhnutelné a někdo se rozhodne změnit cestu na něco jiného. Když se změní adresa URL, pak musíte zajistit, aby všechny existující odkazy byly aktualizovány tak, aby ukazovaly na nové umístění.

Nemuseli byste místo toho, abyste museli doslovně sledovat cesty URL, raději prostě říct aplikaci, aby „přešla na stránku Produkty“? Tím, že aplikaci umožníte, aby se sama starala o navigaci, jste zbaveni nutnosti znát doslovnou cestu a jste chráněni před nefunkčními odkazy způsobenými nevyhnutelností změn. Použití stavů vám poskytuje tuto úroveň flexibility. Stav zapouzdřuje umístění URL, název stavu, specializované údaje pro zobrazení, identifikuje způsob vyhledávání nebo generování zobrazení a může dokonce vystavit vlastní události.

Představujeme Angular UI Router

Angular UI Router je framework, který zcela nahrazuje nativní směrování dostupné v AngularJS. UI Router je velmi podobný nativnímu směrování AngularJS v tom, že aplikace se skládají ze skořápky, která obsahuje zástupný prvek pro dynamický obsah. Obrázek 1 ukazuje, jak shell aplikace hostí prvek, který používá direktivu ui-view. Jak jsou ve frameworku vyhodnocována stavová pravidla, uvnitř zástupného prvku se vykresluje obsah HTML.

Obrázek 1: Framework UI Router přidává obsah HTML do zástupného prvku na stránce.

Angular UI Router je framework, který zcela nahrazuje nativní směrování dostupné v AngularJS.

Kromě vykreslování obsahu HTML podporuje framework UI Router směrování URL, možnost řešit závislosti před inicializací řadičů, pojmenované a vnořené pohledy, filtry utilit, události změny stavu a deklarativní přechody mezi stavy.

Přechod mezi stavy

Přechod mezi různými stavy lze provádět několika různými způsoby. Prvním způsobem je direktiva ui-sref. Pravděpodobně znáte atribut href značky HTML anchor (který představuje hypertextový odkaz); podobně směrnice ui-sref odkazuje na odkaz na stav. Tuto direktivu použijete tak, že deklarujete název stavu s direktivou ui-sref aplikovanou na kotvu. Například:

<a ui-sref="about">About Us</a>

Když rámec UI Router vyhodnotí tuto směrnici, kotva se transformuje tak, aby měla příslušnou hodnotu URL. Například:

<a ui-sref="about" href="#about">About Us</a>

Všimněte si, že prvek je aktualizován tak, aby obsahoval atribut href s hodnotou odpovídající tomu, jak musí být aktualizována adresa URL pro přechod na stránku O nás. Směrnice ui-sref je poměrně flexibilní. Podporuje jednoduché scénáře i způsoby, jak se vypořádat s vnořenými stavy a dokonce i s parametrizovanými hodnotami.

Dalším přístupem pro navigaci mezi stavy je použití metody mimo objekt $state, který je k dispozici kontroléru Angular. V následujícím úryvku vidíte, jak je implementována metoda navigate, která volá objekt $state.go a přechází aplikaci do stavu about.

angular.module('app') .controller('PageController', );

Objekt $state je injektován rámcem UI Router a obsahuje řadu metod, které pomáhají spravovat stavy v aplikaci a manipulovat s nimi. Hodnota zde spočívá v tom, že aplikaci řeknete, aby „přešla“ do stavu about, a jste osvobozeni od znalosti doslovné cesty URL ke stránce.

Stahování a instalace

Existuje řada různých způsobů, jak můžete získat přístup k frameworku UI Router. Nejnovější verzi si můžete stáhnout přímo z repozitáře GitHub na adrese https://github.com/angular-ui/ui-router. Případně můžete framework nainstalovat pomocí služby Bower nebo NuGet nebo dokonce do svých stránek zahrnout odkazy na CDN; obojí je k dispozici na adrese http://cdnjs.com/libraries/angular-ui-router.

Použití frameworku Angular UI Router

Následuje výukový program, který ukazuje, jak vytvořit jednoduchou statickou aplikaci založenou na obsahu pomocí frameworku UI Router. Na obrázku 2 je znázorněna ukázková aplikace domovské stránky, kterou se naučíte sestavit při čtení tohoto článku. Na tomto obrázku vidíte shell aplikace a způsob, jakým je obsah domovské stránky injektován do zástupného prvku pomocí direktivy ui-view.

Obrázek 2 : Domovská stránka a výchozí stav aplikace

Stavy můžete měnit a přejít tak na stránku s kontakty, jak ukazuje obrázek 3. Mechanismus na stránce kontaktu využívá metodu go objektu $state tak, že metodě předá název stavu.

Obrázek 3 : Stránka kontaktu

Další stav je spojen se stránkou seznamu článků, jak je vidět na obrázku 4. Zde je zobrazení zpřístupněno pole dat článku poté, co byly surové hodnoty injektovány do řadiče pomocí UI Frameworku. Navigace na této stránce je usnadněna pomocí direktivy ui-sref, která umožňuje deklarativně vyjádřit stav aplikace, na který chcete přejít.

Obr ure 4 : Stránka seznamu článků

Závěrečná stránka, znázorněná na obrázku 5, ukazuje, jak je v aplikaci použit vnořený stav.

Obrázek 5 : Stránka s detailem článku

Konfigurace

Chcete-li začít pracovat s rámcem UI Router, musíte stránku nakonfigurovat. Prvním krokem je přidání názvu aplikace do atributu ng-app elementu HTML na stránce. Zde je název aplikace jednoduše app.

< html ng-app="app">

Následující krok je přidání direktivy ui-view do elementu na stránce, který bude sloužit jako zástupný prvek pro obsah injektovaný frameworkem. V tomto případě je direktiva přidána do elementu div.

< div ui-view></div>

Nakonec musíte na stránce uvést odkaz na Angular i Angular UI Router.

<script src="scripts/lib/angular.min.js"></script><script src="scripts/lib/angular-ui-router.min.js"></script><script src="scripts/app/app.js"></script>

Tento úryvek kódu obsahuje také odkaz na skript app.js ve složce script/app, který obsahuje kód pro inicializaci aplikace Angular. V procesu inicializace je implementována většina nastavení a rozhraní s rámcem UI Router.

Definování stavů

Jak již bylo uvedeno, základem frameworku UI Router je používání různých stavů v aplikaci. Přístupem ke každému z těchto stavů může aplikace přecházet nebo se přetvářet podle okolností v rámci životního cyklu aplikace. Následující část ukazuje, jak definovat stavy pro aplikaci; veškerý kód je implementován v souboru app.js. Každá část je zkoumána samostatně, ale pokud chcete vidět celý inicializační skript, podívejte se na výpis 1.

Prvním krokem je konfigurace UI Router v aplikaci AngularJS. Po pojmenování modulu máte možnost zaregistrovat framework UI Router jako závislost aplikace přidáním literálu ui.router do pole dependencies. (Všimněte si, jak komentář označuje zástupný symbol pro kód v následujícím úryvku)

angular.module('app', ) .config(/* add configuration here */);

Po definování modulu a zaregistrování závislostí je aplikace nastavena na spuštění anonymní funkce, která se provede během konfigurační fáze aplikace. Zde je do funkce injektováno několik zdrojů, které jsou důležité pro rámec UI Router.

 

Objekt $stateProvider obsahuje metodu state, která umožňuje definovat granulární stavy aplikace, které se mohou, ale nemusí shodovat se změnami URL. Objekt $urlRouterProvider je objekt, který vám dává kontrolu nad způsobem správy a sledování polohy prohlížeče. V kontextu směrovače uživatelského rozhraní se $urlRouterProvider používá k tomu, aby pomohl definovat záchytný navigační scénář. Každý z těchto objektů je podrobněji rozebrán v následujících ukázkách kódu. (Opět si všimněte, že následující úryvky kódu jsou umístěny na pozici zástupného komentáře v předchozím úryvku.)

Každý stav aplikace je definován zadáním názvu a sdělením frameworku, kde má najít značku pro zobrazení. Zde je stav home definován zadáním kořenového umístění pro url a hodnoty pro vlastnost templateUrl.

$stateProvider .state('home', { url: '/', templateUrl: '/partials/home.html' })

Tím se aplikaci říká, aby načetla obsah souboru home.html do zástupného prvku ui-view, když uživatel přejde do kořene aplikace. Zde začínáte vidět jednu z výhod stavově orientovaného směrování. Pokud byste z nějakého důvodu chtěli, aby adresa URL pro domovský stav ukazovala na /home místo na holé kořenové umístění (/), stačilo by tuto změnu provést zde v konfiguraci. Tento stav upouští od jakéhokoli pokročilého nastavení a načítá do prohlížeče statickou stránku. Mohou nastat jiné případy, kdy budete chtít se stavem spojit konkrétní řadič.

Stav contact je nastaven tak, aby načítal značku stránky contact.html do zástupného prvku ui-view. Kromě provedení základní operace nahrazení je ContactsController také přidružen k zobrazení s rozsahem na úrovni elementu DOM, který hostí direktivu ui-view.

 .state('contact', { url: '/contact', templateUrl: '/partials/contact.html', controller: 'ContactController', })

Jak ukazuje obrázek 3, stránka Kontakt obsahuje tlačítko pro přechod na stránku Články. Navigace je provedena v kontroléru ContactsController a demonstruje, jak zapojit kontrolér do zobrazení načítaného na vyžádání pomocí frameworku UI Router.

Stav stránky Článek posouvá konfiguraci o krok dále tím, že do objektu přidává hodnoty, které řeší všechny nakonfigurované hodnoty definované v objektu. Účelem tohoto stavu je vykreslit seznam dostupných článků na webu. Tento stav je nastaven tak, aby měl kontrolér k dispozici informace o článku ještě před jeho instancí. V následujícím úryvku stav definuje hodnotu v objektu resolve.

 .state('articles', { url: '/articles', templateUrl: '/partials/articles.html', resolve: { articles: 'ArticlesService' }, controller: 'ArticlesController' })

V tomto případě vlastnost articles ukazuje na řetězec ArticlesService. Když předáte řetězec jako hodnotu vlastnosti resolve, framework kontaktuje službu registrovanou pod stejným názvem a přeloží službu až na její konečnou hodnotu. V tomto případě služba ArticlesService vrací slib, takže přidružený řadič není instancován, dokud není slib služby vyřešen a konečný objekt není k dispozici jako injektovatelná hodnota pro řadič. Implementace služby ArticlesService je k dispozici v Listingu 3.

Po vykreslení seznamu článků uživateli, jak je znázorněno na obrázku 4, může uživatel vybrat článek a proniknout do obsahu webu. Tato akce je reprezentována vnořeným stavem. Všimněte si, že název stavu obsahuje tečku (.) mezi články a article, která označuje vztah rodiče a potomka mezi stavy.

 .state('articles.article', { url: '/:pageName', templateUrl: function ($stateParams) { return '/partials/articles/' + $stateParams.pageName + '.html'; } });

Zde je použito zvláštní pravidlo, jak se vyhodnocuje vlastnost url. Protože se jedná o vnořený pohled (jak je uvedeno tečkou v názvu stavu), bude hodnota vlastnosti url spojena s hodnotou url nadřazeného stavu. To znamená, že všechny odpovídající stavy budou mít adresu URL, která začíná /articles a poté obsahuje název stránky článku.

Přítomnost dvojtečky (:) svědčí o parametru URL. Zavedením parametru do adresy URL se definice stavu stává dostatečně flexibilní, aby mohla zpracovat jakýkoli stav, který odpovídá vztahu, který má se svým nadřazeným stavem. Tento stav také obsahuje funkci, která je spuštěna za účelem vrácení hodnoty pro templateUrl. Použití funkce zde dává možnost použít parametry definované v url daného stavu. Jakýkoli název, který dáte parametru ve vlastnosti url, odpovídá názvu vlastnosti objektu $stateParams. Tento stav tedy přebírá pageName předané v URL, které použije ve funkci templateUrl pro přístup k jednotlivým souborům s obsahem, které jsou nakonec injektovány do elementu hostujícího direktivu ui-view.

Jedná se o poslední stav definovaný v aplikaci. Chcete-li vidět, jak jsou všechny stavy implementovány ve skutečném inicializačním skriptu, podívejte se na výpis 1.

Poslední příkaz, který je nutné aplikaci zadat, je to, co má udělat, pokud se uživatel pokusí přistoupit na adresu URL, která není definována v metodě configure. Pomocí metody otherwise z objektu $urlRouterProvider jsou všechny nerozpoznané adresy URL zahozeny a aplikace je přesměrována na výchozí umístění. V tomto případě je aplikace nakonfigurována tak, aby byla přesměrována na kořenovou adresu URL, pokud daná adresa URL neodpovídá definovanému stavu.

$urlRouterProvider.otherwise('/');

Nyní, když jsou definovány jednotlivé stavy aplikace, můžete začít věnovat pozornost vytváření služby ArticlesService.

Resolving Data with the Articles Service

Konfigurace stavu článku obsahuje hodnotu pro volbu resolve. Tento objekt je nakonfigurován tak, aby měl ve vlastnosti articles nastavenou řetězcovou hodnotu ArticlesService (kontext viz výpis 1). Poskytnutí řetězce objektu resolve říká frameworku, aby vyhledal službu registrovanou v aplikaci a resolvoval službu až na její konečnou hodnotu. Služba ArticlesService je implementována tak, aby vracela slib.

angular.module('app').factory('ArticlesService', ); return deferred.promise; }]);

Zde služba používá službu $q k vytvoření slibu, který vrací pole. V tomto případě jsou hodnoty zadány natvrdo, ale v reálném kontextu může být potřeba přistupovat ke vzdálenému serveru a poskytovat data. V každém případě musí být služba plně vyřešena, než rámec směrovače předá provedení přidruženému řadiči. Proto je při vyvolání stavu článku nakonec kontroléru předáno pole objektů článku jako závislost.

Použití vyřešených dat v kontroléru ArticlesController

Jednou z výhod použití frameworku UI Router je možnost vynucení oddělení zájmů. Protože stav articles implementuje objekt resolve, je do kontroléru injektováno surové pole článků.

angular.module('app') .controller('ArticlesController', );

Tento přístup je lepší než požadavek, aby kontrolér ArticlesController „věděl“ o službě ArticlesService, protože je mnohem snazší zesměšnit surové pole objektů pro účely testování, než se zabývat zesměšňováním samotné služby. Úplnou implementaci pro kontroléry aplikace naleznete v Listingu 2.

Vyrenderování seznamu článků

Teď, když aplikace přešla do stavu článku a kontrolér má v oboru působnosti nastaveno vyřešené pole článků, je zobrazení nyní připraveno k vykreslení. Zobrazení článků se skládá ze dvou částí. První je další zástupný div, který používá direktivu ui-view za účelem vytvoření vnořeného zobrazení. Druhou je neuspořádaný seznam různých článků dostupných na webu. Takto konstruované zobrazení umožňuje klikat na různé názvy článků, zatímco seznam článků zůstává na stránce. (Příklad vidíte na obrázku 5.) To je možné, protože obsah stránky se načítá do ui-view na úrovni článku, zatímco stránka jako celek se vykresluje v ui-view v shellu aplikace. Úplná implementace aplikačního shellu je k dispozici v Seznamu 4.

Následující úryvek kódu demonstruje, jak zobrazení článků implementuje vnořené zobrazení.

<div ui-view> <!-- default content goes here --></div>...<ul class="list-group"> <li class="list-group-item" c> <a ui-sref="articles.article({pageName: '{{article.pageName}}'})"> {{article.title}}</a> </li></ul>

Tato značka využívá rámec UI Router třemi způsoby. Za prvé, prvek div používá direktivu ui-view jako zástupný prvek, a jak je uvedeno v komentáři, můžete do zástupného prvku předat výchozí obsah, který se vykreslí předtím, než framework vykreslí jakýkoli obsah. Výpis 5 ukazuje, jak je statická zpráva použita jako zástupný obsah na stránce před načtením jakéhokoli obsahu do zobrazení.

Druhé, prvek anchor má použitou direktivu ui-sref. Ta signalizuje rámci UI Router, aby tento odkaz zpracoval v kontextu rámce a nakonec vykreslil standardní hodnotu href, která odpovídá adrese URL pro deklarovaný stav na základě nastavení definovaných v konfiguraci aplikace (viz výpis 1).

Třetí způsob použití frameworku spočívá v tom, že hodnota směrnice ui-sref přijímá výraz pro vygenerování správné hodnoty URL pro vnořený stav. Zde je do hierarchie vnořeného stavu (v tomto případě articles.article) předán hash, kde je hodnota pro pageName vázána na pageName příchozího článku. Když framework UI Router vyhodnotí tento výraz, je pro každý článek, který odpovídá definovaným pravidlům stavu, vygenerována odpovídající hodnota URL.

Více abstraktní navigace

Posledním řadičem, který je třeba implementovat, je řadič ContactController, který používá metodu go parametru stavu k navigaci aplikace do nového stavu.

app.controller('ContactController', );

Prostým voláním go s názvem stavu se zde kontrolér stará pouze o deklaraci stavu, do kterého chcete přejít, místo aby se snažil sledovat konkrétní schéma směrování v aplikaci.

Závěr

Ačkoli je AngularJS vybaven funkční implementací směrování, můžete si rychle uvědomit výhody použití stavového směrování pro netriviální aplikace. Framework UI Router poskytuje snadné způsoby, jak definovat stavy, řešit závislosti a využívat vnořené pohledy. Chcete-li získat ještě více informací o tom, co tento rámec umí, určitě navštivte domovskou stránku projektu na GitHubu na adrese https://github.com/angular-ui/ui-router/.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.