Одним из наиболее важных понятий в веб-разработке является написание чистого, модульного кода. Это особенно актуально при работе в команде над очень сложными приложениями. Фреймворк Angular был создан для создания высокоуровневых приложений, которые могут быть очень сложными и очень быстрыми, что, в свою очередь, делает написание модульного кода еще более актуальным. Одним из инструментов, который может сильно помочь вам в этом квесте, является Angular UI Router , который был создан для управления различными состояниями вашего веб-приложения. В отличие от собственной реализации маршрутизации AngularJS, она дает вам полный контроль над каждым из ее представлений.
Если вы ранее использовали ui-router, вы можете знать, как точка-нотация используется для определения дочерних состояний внутри родительского состояния . Однако вы можете не знать, как библиотека ui-router работает с именованными представлениями, вложенными в родительское состояние. И это то, что я собираюсь объяснить сегодня.
Я собираюсь показать вам, как ui-router использует абсолютные имена, чтобы дать вам полный контроль над тем, где отображаются определенные части веб-приложения. Это позволяет легко добавлять и удалять различные части интерфейса для создания модульного приложения, построенного из разных компонентов. В частности, я покажу вам, как сопоставить панель навигации, некоторый контент тела и нижний колонтитул с определенным состоянием. Как всегда, код для этого руководства можно найти на GitHub, а также вы можете найти демонстрацию в конце статьи .
Начиная
Уделите минуту просмотру файлов, составляющих эту демонстрацию (доступно по ссылке выше на GitHub). Вы можете видеть, что у нас есть файл index.html
который мы включаем AngularJS, а также библиотеку для ui-router. В этом файле у нас также есть две директивы ui-view
в которые мы будем вставлять наш контент. Далее у нас есть файл app.js
, который будет содержать код для нашего приложения Angular и каталог templates
. Этот каталог будет использоваться для размещения всех наших различных взглядов. Хотя эта папка не является необходимой, в ваших интересах определенно использовать какую-то структуру при создании приложений с Angular. Как видите, я включил папку assets
папку templates
. Именно здесь я хотел бы сохранить свои повторно используемые компоненты: верхние колонтитулы, навигационные панели, нижние колонтитулы и т. Д. Я подумал, что это соглашение может оказаться полезным, поскольку оно сохраняет ваш код чрезвычайно модульным.
UI-маршрутизатор
Добавить зависимость к UI-роутеру
Давайте начнем настройку нашего приложения. Внутри нашего файла app.js
нам нужно добавить зависимость от ui-router в наш основной угловой модуль.
angular.module('app', ['ui.router'])
Конфигурирование наших маршрутов
Как только это будет сделано, мы можем перейти к объекту config
нашего приложения. Здесь мы будем иметь дело с $ stateProvider и $ urlRouterProvider , поэтому нам нужно внедрить их в наш объект конфигурации, чтобы они были доступны.
Затем мы хотим передать URL нашего домашнего состояния в $urlRouterProvider.otherwise()
, чтобы оно по умолчанию отображало наше приложение в этом состоянии. Затем нам нужно будет использовать $stateProvider
, с которым мы будем иметь дело до конца урока. $stateProvider
— это то, что ui-router дает разработчикам использовать при маршрутизации приложений. Состояние соответствует «месту» в приложении с точки зрения общего пользовательского интерфейса и навигации. Состояние описывает, как выглядит пользовательский интерфейс и что он делает в этом месте. Он работает так же, как ngRoute
использует routeProvider
.
Ниже показано, как должен выглядеть файл app.js
в данный момент. Как только мы настроили urlRouterProvider
, мы используем $stateProvider
для определения различных состояний приложения. В этом случае мы определяем состояние с именем home, и настраивается только URL.
angular.module( 'app' , [ 'ui.router' ]) .config([ '$stateProvider' , '$urlRouterProvider' , function ( $stateProvider , $urlRouterProvider ) { $urlRouterProvider .otherwise( '/' ); $stateProvider .state( 'home' , { url: '/' }); } ]);
Объект Views
Теперь, когда вы настроили «голые кости», вам нужно определить объект views
внутри $stateProvider
. Он должен быть размещен сразу после URL-адреса домашнего государства. Внутри этого объекта мы собираемся определить имена наших представлений, а также пути их шаблонов. Здесь вы также можете определить такие вещи, как контроллеры; однако, для краткости я пропустил это в этом уроке.
Двигаясь дальше, мы должны сначала создать и определить безымянное представление, которое будет нацелено на родительское состояние — которое в этом случае является домашним. templateUrl
этого безымянного представления по существу свяжет их вместе. Это называется относительным именованием и указывает angular вставить это безымянное представление в <div ui-view>
внутри нашего файла index.html
. Ваш код должен теперь повторить app.js
ниже.
angular.module( 'app' , [ 'ui.router' ]) .config([ '$stateProvider' , '$urlRouterProvider' , function ( $stateProvider , $urlRouterProvider ) { $urlRouterProvider .otherwise( '/' ); $stateProvider .state( 'home' , { url: '/' , views: { '' : { templateUrl: './templates/main.html' }, } }); } ]);
Как видите, безымянное представление main.html
в main.html
, который должен напоминать приведенный ниже код.
< div ui-view = "nav" > </ div > < h1 class = "text-center" > This content is in main.html </ h1 > < div ui-view = "body" > </ div > < div ui-view = "footer" > </ div >
Файл main.html
включает в себя три именованных представления — nav, body и footer. Чтобы эти компоненты отображались в исходном состоянии, мы должны определить их, используя абсолютное именование. В частности, мы должны использовать синтаксис @
чтобы сообщить AngularJS, что эти компоненты нашего приложения должны быть сопоставлены с определенным состоянием. Это следует синтаксису viewName@stateName
и указывает нашему приложению использовать именованные представления из абсолютного или определенного состояния. Вы можете прочитать больше об относительных и абсолютных именах здесь .
Вы увидите, что @home
используется в нашем объекте конфигурации, чтобы Angular знал, что наши именованные представления нацелены на наше домашнее состояние. Если эти абсолютные имена отсутствуют, приложение не будет знать, где найти эти именованные представления. Тем не менее, посмотрите ниже и посмотрите, как приложение должно быть маршрутизировано.
angular.module( 'app' , [ 'ui.router' ]) .config([ '$stateProvider' , '$urlRouterProvider' , function ( $stateProvider , $urlRouterProvider ) { $urlRouterProvider .otherwise( '/' ); $stateProvider .state( 'home' , { url: '/' , views: { '' : { templateUrl: './templates/main.html' }, 'nav@home' : { templateUrl: './templates/assets/nav.html' }, 'body@home' : { templateUrl: './templates/body.html' }, 'footer@home' : { templateUrl: './templates/assets/footer.html' } } }); } ]);
И это то, что мы в конечном итоге:
Почему это здорово
Как я уже говорил ранее, абсолютное именование делает ваш код чрезвычайно модульным. В этом уроке я разместил все наши представления внутри папки шаблонов. Однако вы можете пойти дальше и создать папки для различных представлений ваших приложений. Это позволяет вам повторно использовать шаблоны во всем приложении, а также в будущих проектах! Библиотека ui-router позволяет чрезвычайно легко использовать различные компоненты веб-приложения, такие как верхний и нижний колонтитулы для определенных представлений. Это облегчит многократное использование кода в разных проектах и определенно сэкономит ваше время.
Вывод
Существует гораздо более сложная, высокоуровневая вложенность, которую вы можете сделать с абсолютными именами — это был только один пример! Тем не менее, я надеюсь, что вы получили более глубокое представление о некоторых вещах, которые делает возможным использование ui-router. В этой статье, написанной Антонио Моралесом , он очень хорошо объясняет разницу между абсолютным и относительным именованием, дочерними состояниями и другими аспектами библиотеки ui-router Angular. Как всегда, дайте мне знать, если у вас есть какие-либо вопросы относительно этого урока. Я был бы рад ответить на них.