...

четверг, 15 августа 2013 г.

Nested routing в AngularJS

В AngularJS, как известно, нет возможности штатными средствами сделать многоуровневую маршрутизацию, в которой перезагрузка нижних уровней маршрутов бы не приводила к пересозданию элементов верхнего уровня. Стандартный сервис $route инициализирует вид, контроллер и его scope целиком каждый раз, когда изменяется URL страницы.

Для решения этой проблемы написано несколько сторонних решений, включая известный ui-router. По ряду причин ни одно из решений для некоторых моих проектов не подошло, и я написал собственную библиотеку, которую здесь и представляю: angular-route-segment.


Что она позволяет делать?



Демонстрационный пример здесь: artch.ru/angular-route-segment/example/

Исходники примера в каталоге example на Гитхабе.


Библиотека служит заменой стандартному сервису $route. Каждый маршрут представляется в виде иерархической древовидной цепочки сегментов, перечисленных через точку, каждый из которых возможно конфигурировать в отдельности.



angular.module('app').config(function ($routeSegmentProvider) {

$routeSegmentProvider.

when('/section1', 's1.home').
when('/section1/prefs', 's1.prefs').
when('/section1/:id', 's1.itemInfo.overview').
when('/section1/:id/edit', 's1.itemInfo.edit').
when('/section2', 's2').

segment('s1', {
templateUrl: 'templates/section1.html',
controller: MainCtrl}).

within().

segment('home', {
templateUrl: 'templates/section1/home.html'}).

segment('itemInfo', {
templateUrl: 'templates/section1/item.html',
controller: Section1ItemCtrl,
dependencies: ['id']}).

within().

segment('overview', {
templateUrl: 'templates/section1/item/overview.html'}).

segment('edit', {
templateUrl: 'templates/section1/item/edit.html'}).

up().

segment('prefs', {
templateUrl: 'templates/section1/prefs.html'}).

up().

segment('s2', {
templateUrl: 'templates/section2.html',
controller: MainCtrl});


Допускается использовать и иной синтаксис, без прохода по дереву:



$routeSegmentProvider.segment('s1', {
templateUrl: 'templates/section1.html',
controller: MainCtrl});

$routeSegmentProvider.within('s1').segment('home', {
templateUrl: 'templates/section1/home.html'});

$routeSegmentProvider.within('s1').segment('itemInfo', {
templateUrl: 'templates/section1/item.html',
controller: Section1ItemCtrl,
dependencies: ['id']});


С помощью директивы app-view-segment (замена штатному ng-view) указывается место в DOM страницы, куда каждый из уровней сегментов должен быть отрендерен:


index.html



<ul>
<li><a href="/section1">Section 1</a></li>
<li><a href="/section2">Section 2</a></li>
</ul>
<div id="contents" app-view-segment="0"></div>


section1.html (будет загружен в элемент div#contents)



<h4>Section 1</h4>
Section 1 contents.
<div app-view-segment="1"></div>


В этот <div> может быть загружен следующий сегмент, и так далее.


Такой подход, в сочетании с некоторыми продвинутыми фичами по конфигурированию, позволяет делать довольно сложные вещи с маршрутизацией в приложении.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers. Five Filters recommends: 'You Say What You Like, Because They Like What You Say' - http://www.medialens.org/index.php/alerts/alert-archive/alerts-2013/731-you-say-what-you-like-because-they-like-what-you-say.html


Комментариев нет:

Отправить комментарий