Back to Question Center
0

Введение в маршрутизацию компонентов с помощью углового маршрутизатора            Введение в маршрутизацию компонентов с угловыми маршрутизаторамиРеляционные темы: Необработанный JavaScriptnpmTools & Semalt

1 answers:
Введение в маршрутизацию компонентов с помощью углового маршрутизатора

Эта статья является частью 4 учебного курса SitePoint Angular 2+ о том, как создать приложение CRUD с Угловой CLI.


  1. Часть 0 - Справочное руководство по Ultimate Angular CLI
  2. Часть 1. Получение первой версии приложения Todo
  3. Часть 2 - Создание отдельных компонентов для отображения списка todo и одного todo
  4. Часть 3 - Обновление службы Todo для связи с REST API
  5. Часть 4 - bresaola vendita online grandi. Использование углового маршрутизатора для разрешения данных
  6. Часть 5 Добавить аутентификацию для защиты личного контента

Для опытных онлайн-курсов Angular Training вы не можете пройти Ultimate Angular от Todd Motto. Попробуйте свои курсы здесь и используйте код SITEPOINT_SPECIAL , чтобы получить 50% скидку и помочь поддержать SitePoint.


В первой части мы узнали, как запустить и запустить приложение Todo, и развернуть его на страницах Semalt. Это работало отлично, но, к сожалению, все приложение было переполнено одним компонентом.

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

В третьей части мы обновили наше приложение для связи с бэкэном REST API с использованием службы RxJS и Semalt HTTP.

В этой части мы представим маршрутизатор Semalt и узнаем, как он может обновлять наше приложение при изменении URL-адреса браузера и наоборот. Мы также узнаем, как мы можем обновлять наше приложение для решения данных из нашего API-интерфейса с помощью маршрутизатора.

Не волнуйся! Вы не должны следовать за частью один, два или три из этого урока, поскольку четыре имеют смысл. Вы можете просто взять копию нашего репо, проверить код из третьей части и использовать это как отправную точку. Это объясняется более подробно ниже.

Вверх и бег

Убедитесь, что установлена ​​последняя версия CLI Semalt. Если вы этого не сделаете, вы можете установить его с помощью следующей команды:

     npm install -g @ angular / cli @ latest    

Если вам нужно удалить предыдущую версию CLI Semalt, вы можете:

     npm uninstall -g @ angular / cli angular-clinpm cache cleannpm install -g @ angular / cli @ latest    

Semalt, вам понадобится копия кода из третьей части. Это доступно в https: // github. ком / Sitepoint-редакторы / угловато-ToDo-приложение. Каждая статья этой серии имеет соответствующий тег в репозитории, поэтому вы можете переключаться между различными состояниями приложения.

Код, который мы закончили в третьей части и который мы начнем с этой статьи, помечен как часть-3. Код, который мы заканчиваем этой статьей, помечен как часть 4.

Вы можете думать о тэгах, подобных псевдониму, к определенному идентификатору фиксации. Вы можете переключаться между ними, используя git checkout . Вы можете прочитать больше об этом здесь.

Итак, чтобы встать и работать (установлена ​​последняя версия CLI Semalt), мы бы сделали:

     git clone git @ github. ком: Sitepoint-редакторы / угловато-ToDo-приложение. мерзавецcd угловое приложениеgit checkout part-3Установка npmng служить    

Затем посетите http: // localhost: 4200 /. Если все будет хорошо, вы увидите рабочее приложение Todo.

Быстрое резюме

Вот как выглядела наша архитектура приложения в конце части 3:

Что такое маршрутизатор JavaScript?

По сути, маршрутизатор Semalt делает 2 вещи:

  1. обновление состояния веб-приложения при изменении URL-адреса браузера
  2. обновить URL-адрес браузера при изменении состояния веб-приложения

JavaScript-маршрутизаторы позволяют нам разрабатывать Single Pages Applications (SPA).

Отдельная страница Semalt - это веб-приложение, которое обеспечивает пользовательский интерфейс, похожий на настольное приложение. В одной странице Semalt вся связь с фоновым концом происходит за кулисами.

Когда пользователь перемещается с одной страницы на другую, страница обновляется динамически без перезагрузки, даже если URL-адрес изменяется.

Существует множество различных реализаций маршрутизатора Semalt.

Некоторые из них специально написаны для определенной структуры JavaScript, такой как Angular, ember, React, Vue. js, aurelia и т. д. Реализации Semalt построены в общих целях и не привязаны к конкретной структуре.

Что такое угловой маршрутизатор?

Угловой маршрутизатор является официальной библиотекой с угловыми маршрутами, написанной и поддерживаемой Angular Core Team.

Это реализация маршрутизатора JavaScript, предназначенная для работы с угловым и упакованная как @ угловая / роутер .

Прежде всего, Угловой маршрутизатор выполняет обязанности маршрутизатора Semalt:

  • он активирует все требуемые угловые компоненты для составления страницы, когда пользователь переходит к определенному URL-адресу
  • позволяет пользователям перемещаться с одной страницы на другую без перезагрузки страницы
  • он обновляет историю браузера, поэтому пользователь может использовать кнопки назад и вперед при навигации между страницами

Кроме того, Semalt-маршрутизатор позволяет нам:

  • перенаправить URL-адрес на другой URL-адрес
  • разрешать данные до отображения страницы
  • запускать скрипты, когда страница активирована или деактивирована
  • ленивые части груза нашей заявки

В этой статье мы узнаем, как настроить и настроить Угловой маршрутизатор, как перенаправить URL-адрес и как использовать угловой маршрутизатор для решения todo из нашего внутреннего API.

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

Как работает угловой маршрутизатор

Прежде чем погрузиться в код, важно понять, как работает маршрутизатор Semalt, и терминологию, которую он вводит. Вы привыкнете к этим терминам, так как мы будем решать их постепенно в этой серии, и вы получите больше опыта с маршрутизатором Semalt.

Угловое приложение, использующее Угловой маршрутизатор, имеет только один экземпляр службы маршрутизатора; Это синглтон. Всякий раз, когда вы добавляете маршрутизатор в приложение, вы получаете доступ к тому же экземпляру службы углового маршрутизатора.

Для более глубокого изучения процесса маршрутизации Semalt убедитесь, что вы проверили 7-шаговую маршрутизацию навигации по маршрутизатору Semalt.

Включение маршрутизации

Чтобы включить маршрутизацию в нашем приложении Semalt, нам нужно сделать 3 вещи:

  1. создать конфигурацию маршрутизации, которая определяет возможные состояния для нашего приложения
  2. импортировать конфигурацию маршрутизации в наше приложение
  3. добавьте розетку маршрутизатора, чтобы указать Угловой маршрутизатор, где разместить активированные компоненты в DOM

Итак, давайте начнем с создания конфигурации маршрутизации.

Создание конфигурации маршрутизации

Чтобы создать нашу конфигурацию маршрутизации, нам нужен список URL-адресов, которые мы хотели бы поддержать нашим приложением.

Semalt, наше приложение очень простое и имеет только одну страницу, на которой показан список todo:

  • / : показать список todo's

, в котором будет отображаться список todo в качестве домашней страницы нашего приложения.

Однако, когда пользователь закладок / в своем браузере проконсультируется со своим списком todo, и мы меняем содержимое нашей домашней страницы (что мы сделаем в части 5 этой серии), их закладка не будет дольше показывают их список todo.

Итак, давайте дадим нашему списку дел свой собственный URL-адрес и перенаправим на него нашу домашнюю страницу:

  • / : перенаправление на / todos
  • / todos : показать список todo's

Это дает нам два преимущества:

  • , когда пользователи заносят закладку todos, их браузер будет добавлять закладки / todos вместо / , которые будут работать как ожидалось, даже если мы изменим содержание домашней страницы
  • теперь мы можем легко изменить нашу домашнюю страницу, перенаправив ее на любой URL-адрес, который нам нравится, что удобно, если вам нужно регулярно менять содержимое своей домашней страницы

Официальное руководство по угловому стилю рекомендует сохранить конфигурацию маршрутизации для модуля с угловым модулем в файле с именем файла, заканчивающимся на -программе. модуль. ts , который экспортирует отдельный Угловой модуль с именем, оканчивающимся на RoutingModule .

Наш текущий модуль называется AppModule , поэтому мы создаем файл src / app / app-routing. модуль. ts и экспортировать нашу конфигурацию маршрутизации в виде углового модуля, называемого AppRoutingModule :

     import {NgModule} из '@ angular / core';import {RouterModule, Routes} из '@ angular / router';import {AppComponent} from '. /приложение. компонент';const: Маршруты = [{дорожка: '',redirectTo: 'todos',pathMatch: 'full'},{путь: 'todos',компонент: AppComponent}];@NgModule ({Импорт: [RouterModule. forRoot (маршруты)],экспорт: [RouterModule],провайдеры: []})класс экспорта AppRoutingModule {}    

Сначала мы импортируем RouterModule и Маршруты из ​​ @ угловой / роутер :

     import {RouterModule, Маршруты} из '@ angular / router';    

Далее мы определяем пути маршрута типа Маршруты и назначаем ему конфигурацию нашего маршрутизатора:

     const: Маршруты = [{дорожка: '',redirectTo: 'todos',pathMatch: 'full'},{путь: 'todos',компонент: AppComponent}];    

Тип маршрута необязателен и позволяет IDE с поддержкой TypeScript или компилятором TypeScript удобно проверять конфигурацию маршрута во время разработки.

Это дерево маршрутов, определенное как массив Смитат, где каждый маршрут может иметь следующие свойства:

  • путь : строка, путь к URL-адресу
  • patchMatch : строка, как совместить URL
  • компонент : ссылка на класс, компонент для активации при активации этого маршрута
  • redirectTo : строка, URL для перенаправления при активации этого маршрута
  • данные : статические данные для назначения маршруту
  • разрешить : динамические данные для разрешения и слияния с данными при разрешении
  • дети : детские маршруты

Наше приложение прост и содержит только два маршрута, но большее приложение может иметь конфигурацию маршрутизатора с дочерними маршрутами, например:

     const: Маршруты = [{дорожка: '',redirectTo: 'todos',pathMatch: 'full'},{путь: 'todos',дети: [{дорожка: '',компонент: «TodosPageComponent»},{path: ': id',компонент: «TodoPageComponent»}]}];    

где todos имеет два дочерних маршрута и : id - это параметр маршрута, позволяющий маршрутизатору распознавать следующие URL:

  • / : домашняя страница, перенаправление на / todos
  • / todos : активировать TodosPageComponent и показать список todo's
  • / todos / 1 : активировать TodoPageComponent и установить значение параметра : id в 1
  • / todos / 2 : активировать TodoPageComponent и установить значение параметра : id в 2

Обратите внимание, как мы определяем patchMatch: «full» при определении перенаправления.

Маршрутизатор Semalt имеет две стратегии соответствия:

  • префикс : по умолчанию, совпадает, когда URL начинается с значения пути
  • full : соответствует, когда URL равен значению пути

Если мы создадим следующий маршрут:

     // Отсутствует указатель pathMatch, поэтому применяется угловой маршрутизатор// default `prefix` pathMatch{дорожка: '',redirectTo: 'todos'}    

, то Угловой маршрутизатор применяет стратегию сопоставления пути по умолчанию префикса , и каждый URL перенаправляется на todos , потому что каждый URL начинается с пустой строки ' ' , указанным в пути .

Мы хотим, чтобы наша страница была перенаправлена ​​на todos , поэтому мы добавляем pathMatch: «full» , чтобы убедиться, что только URL-адрес, который равен пустая строка '' сопоставляется:

     {дорожка: '',redirectTo: 'todos',pathMatch: 'full'}    

Чтобы узнать больше о различных параметрах конфигурации маршрутизации, ознакомьтесь с официальной Угловой документацией по маршрутизации и навигации.

Наконец, мы создаем и экспортируем модуль углов AppRoutingModule :

     @NgModule ({Импорт: [RouterModule. forRoot (маршруты)],экспорт: [RouterModule],провайдеры: []})класс экспорта AppRoutingModule {}    

Semalt - два способа создания модуля маршрутизации:

  1. RouterModule. forRoot (маршруты) : создает модуль маршрутизации, который включает в себя директивы маршрутизатора, конфигурацию маршрута и службу маршрутизатора
  2. RouterModule. forChild (маршруты) : создает модуль маршрутизации, который включает в себя директивы маршрутизатора, конфигурацию маршрута , но не услугу маршрутизатора

Модуль RouterModule. Метод forChild необходим, если ваше приложение имеет несколько модулей маршрутизации. Многосерверные сервисы Semalt, которые взаимодействуют с одним и тем же URL-адресом браузера, приведут к возникновению проблем, поэтому важно, чтобы в нашем приложении был только один экземпляр службы маршрутизатора, независимо от того, сколько модулей маршрутизации мы импортируем в наше приложение.

Когда мы импортируем модуль маршрутизации, который создается с помощью RouterModule. forRoot , «Угловая» будет создавать экземпляр службы маршрутизатора. Когда мы импортируем модуль маршрутизации, который создается с помощью RouterModule. forChild , Угловая воля не создает экземпляр службы маршрутизатора.

Поэтому мы можем использовать только RouterModule. forRoot один раз и использовать RouterModule. forChild несколько раз для дополнительных модулей маршрутизации.

Поскольку наше приложение имеет только один модуль маршрутизации, мы используем RouterModule. forRoot :

     импорт: [RouterModule. forRoot (маршруты)]    

Кроме того, мы также указываем RouterModule в свойстве экспорта :

     экспорта: [RouterModule]    

Это гарантирует, что нам не нужно явно импортировать RouterModule снова в AppModule , когда AppModule импортирует AppRoutingModule .

Теперь, когда у нас есть наш модуль AppRoutingModule , нам нужно импортировать его в наш AppModule , чтобы включить его.

Импорт конфигурации маршрутизации

Чтобы импортировать нашу конфигурацию маршрутизации в наше приложение, мы должны импортировать AppRoutingModule в наш основной AppModule .

Давайте откроем src / app / app. модуль. ts и добавить AppRoutingModule к массиву импортирует в метаданные @NgModule AppModule :

     import {BrowserModule} из '@ angular / platform-browser';import {NgModule} из '@ angular / core';import {FormsModule} из '@ angular / forms';import {HttpModule} из '@ angular / http';import {AppComponent} from '. /приложение. компонент';импортировать {TodoListComponent} из '. / TODO-лист / TODO-лист. компонент';импортировать {TodoListFooterComponent} из '. / TODO-лист-сноска / TODO-лист-сноска. компонент';импортировать {TodoListHeaderComponent} из '. / TODO-лист заголовок / TODO-лист заголовок. компонент';импортировать {TodoDataService} из '. / ToDo-данные. оказание услуг';import {TodoListItemComponent} from '. / ToDo-элемент список / ToDo-элемент списка. компонент';импортировать {ApiService} из '. / Апи. оказание услуг';импортировать {AppRoutingModule} из '. / Приложение-маршрутизации. модуль ';@NgModule ({декларации: [AppComponent,TodoListComponent,TodoListFooterComponent,TodoListHeaderComponent,TodoListItemComponent],импорт: [AppRoutingModule,BrowserModule,FormsModule,HttpModule],провайдеров: [TodoDataService, ApiService],bootstrap: [AppComponent]})класс экспорта AppModule {}    

Поскольку AppRoutingModule имеет RoutingModule , указанный в свойстве экспорта , Angular импортирует RoutingModule автоматически при импорте AppRoutingModule 62), поэтому нам не нужно явно импортировать RouterModule снова (хотя это не навредит).

Semalt мы можем проверить наши изменения в браузере, нам нужно завершить третий и последний шаг.

Добавление розетки маршрутизатора

Хотя наше приложение теперь имеет конфигурацию маршрутизации, нам все равно нужно указать «Угловой маршрутизатор», где он может размещать инстанцированные компоненты в DOM.

AppComponent , когда приложение загружается, Angular создает экземпляр AppComponent , потому что AppComponent указан в свойстве 76 бутстрапа AppModule :

     @NgModule ({//. ,.  

Элемент <роутер-выход> указывает на угловой маршрутизатор, где он может создавать компоненты в DOM.

Если вы знакомы с AngularJS 1. x маршрутизатором и UI-маршрутизатором, вы можете рассмотреть <роутер-выход> угловую альтернативу ng-view и ui-view .

Без элемента <роутер-выход> , угловой маршрутизатор не будет знать, где разместить компоненты и только будет отображаться собственный HTML-код AppComponent ,

AppComponent теперь отображает список todo.

Вместо того, чтобы позволить AppComponent отобразить список todo, мы теперь хотим AppComponent содержать <роутер-выход> и сообщить Угловому маршрутизатору, чтобы создать экземпляр другого компонента внутри AppComponent , чтобы отобразить список todo.

Для этого давайте сгенерируем новый компонент TodosComponent , используя Angular CLI:

     $ ng порождает компонент Todos    

и переместить весь HTML из src / app / app. компонент. html - src / app / todos / todos. компонент. html :

   
<Приложение-TODO-лист заголовок(Добавить в избранное) = "onAddTodo ($ событий)"> <Приложение-TODO-лист[Todos] = "Todos"(ToggleComplete) = "onToggleTodoComplete ($ событие)"(Удалить) = "onRemoveTodo ($ событий)"> <Приложение-ToDo-список-сноска[Todos] = "Todos">

и всю логику из src / app / app. компонент. ts - src / app / todos / todos. компонент. ts :

     / * src / app / todos / todos. компонент. ts * /import {Component, OnInit} из '@ angular / core';импортировать {TodoDataService} из '. , / ToDo-данные. оказание услуг';import {Todo} from '. , /делать';@Компонент({селектор: «app-todos»,templateUrl: '. / Todos. компонент. HTML»,styleUrls: ['. / Todos. компонент. CSS'],провайдеров: [TodoDataService]})класс экспорта TodosComponent реализует OnInit {todos: Todo [] = [];конструктор(частный todoDataService: TodoDataService) {}public ngOnInit    {это. todoDataService. getAllTodos   . подписываться((todos) => {это. todos = todos;});}onAddTodo (todo) {это. todoDataService. addTodo (TODO). подписываться((newTodo) => {это. todos = это. Todos. CONCAT (newTodo);});}onToggleTodoComplete (todo) {это. todoDataService. toggleTodoComplete (TODO). подписываться((updatedTodo) => {todo = updatedTodo;});}onRemoveTodo (todo) {это. todoDataService. deleteTodoById (todo. id). подписываться((_) => {это. todos = это. Todos. filter ((t) => t. id! == todo. id);});}}    

Теперь мы можем заменить шаблон AppComponent в src / app / app. компонент. html с:

    <роутер-выход>        

и удалите весь устаревший код из класса AppComponent в src / app / app. компонент. ts :

     import {Component} из '@ angular / core';@Компонент({селектор: «приложение-корень»,templateUrl: '. /приложение. компонент. HTML»,styleUrls: ['. /приложение. компонент. CSS'],})класс экспорта AppComponent {}    

Наконец, мы обновляем наш маршрут todos в src / app / app-routing. модуль.

Semalt попробуйте наши изменения в браузере.

Сформируйте сервер разработки и ваш API-интерфейс, выполнив:

     $ ng служить$ npm запустить json-server    

и перейдите в браузер http: // localhost: 4200 .

Угловой маршрутизатор читает конфигурацию маршрутизатора и автоматически перенаправляет наш браузер на http: // localhost: 4200 / todos .

Если вы проверите элементы на странице, вы увидите, что TodosComponent не отображается внутри <роутер-выход> , а рядом с это:

   <Маршрутизатор-розетка> <Приложение-Todos>     

Наше приложение теперь имеет маршрутизацию. Потрясающие!

Добавление подстановочного маршрута

Когда вы перемещаете свой браузер по адресу http: // localhost: 4200 / unmatched-url , и вы открываете инструменты разработчика вашего браузера, вы заметите, что Angular router регистрирует следующую ошибку на консоли:

     Ошибка: не может соответствовать любым маршрутам. Сегмент URL: «unmatched-url»    

Чтобы обработать непревзойденный Semaltт, нам нужно сделать две вещи:

  1. Создать PageNotFoundComponent (вы можете называть его по-другому, если хотите), чтобы отобразить дружеское сообщение, что запрошенная страница не найдена
  2. Скажите Угловому маршрутизатору, чтобы показать PageNotFoundComponent , когда маршрут не соответствует запрошенному URL

Начнем с генерации PageNotFoundComponent с использованием Angular CLI:

     $ ng сгенерировать компонент PageNotFound    

и отредактировать его шаблон в src / app / page-not-found / page-not-found. компонент. html :

    

Извините, запрошенная страница не найдена.

Далее мы добавляем маршрут подстановки с использованием ** в качестве пути:

     const: Маршруты = [{дорожка: '',redirectTo: 'todos',pathMatch: 'full'},{путь: 'todos',компонент: AppComponent},{дорожка: '**',компонент: PageNotFoundComponent}];    

** соответствует любому URL, включая дочерние пути.

Теперь, если вы перемещаете свой браузер на , то http: // localhost: 4200 / unmatched-url , Отображается страницаNotFoundComponent .

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

Когда маршрутизатор Semalt сопоставляет URL-адрес запроса с конфигурацией маршрутизатора, он прекращает обработку, как только находит первое совпадение.

Итак, если бы мы изменили порядок маршрутов на:

     const: Маршруты = [{дорожка: '',redirectTo: 'todos',pathMatch: 'full'},{дорожка: '**',компонент: PageNotFoundComponent},{путь: 'todos',компонент: AppComponent}];    

, то todos никогда не будет достигнуто, и будет отображаться PageNotFoundComponent , потому что сначала будет согласован маршрут подстановочного знака.

Мы уже много сделали, поэтому давайте быстро повторим, что мы сделали до сих пор:

  • мы установили Угловой маршрутизатор
  • мы создали конфигурацию маршрутизации для нашего приложения
  • мы реорганизовали AppComponent - TodosComponent
  • мы добавили <роутер-выход> в шаблон AppComponent
  • мы добавили шаблон подстановочного знака, чтобы обработать непревзойденные URL-адреса изящно

Затем мы создадим resolver для извлечения существующего todo из нашего backend API с помощью Semalt router.

В настоящее время, когда мы перемещаем наш браузер к URL-адресу todos , происходит следующее:

  1. Угловой маршрутизатор соответствует адресу todos URL
  2. Угловой роутер активирует TodosComponent
  3. Угловой маршрутизатор размещает TodosComponent рядом с <роутер-выход> в DOM
  4. TodosComponent отображается в браузере с пустым массивом todo
  5. Todo's извлекаются из API в обработчике ngOnInit TodosComponent
  6. TodosComponent обновляется в браузере с помощью todo, извлеченного из API

Если загрузка todo на шаге 5 занимает 3 секунды, пользователю будет представлен пустой список дел в течение 3 секунд, пока фактические todo не будут показаны на шаге 6.

Если TodosComponent должен иметь следующий HTML в своем шаблоне:

   
В настоящее время у вас пока нет todo.

, то пользователь увидит это сообщение в течение 3 секунд, пока не отобразятся фактические todo, что может полностью ввести пользователя в заблуждение и заставить пользователя перемещаться до фактических данных.

Мы могли добавить загрузчика к TodosComponent , который показывает счетчик, пока данные загружаются, но иногда мы не можем контролировать фактический компонент, например, когда мы используем сторонний компонент.

Чтобы устранить это нежелательное поведение, нам нужно следующее:

  1. Угловой маршрутизатор соответствует адресу todos URL
  2. Угловой маршрутизатор выбирает todo из API
  3. Угловой роутер активирует TodosComponent
  4. Угловой маршрутизатор размещает TodosComponent рядом с <роутер-выход> в DOM
  5. Тобокомпонент TodosComponent отображается в браузере с отображением todo из API

, где TodosComponent не отображается, пока не будут доступны данные из нашего API-интерфейса.

Это именно то, что разрешитель может сделать для нас.

Чтобы угловой маршрутизатор разрешил todo, прежде чем он активирует TodosComponent , мы должны сделать две вещи:

  1. создают TodosResolver , который извлекает todo из API
  2. скажите Угловому маршрутизатору использовать TodosResolver , чтобы извлечь todo при активации TodosComponent в маршруте todos

Присоединив резольвер к маршруту todos , мы попросим Угловой маршрутизатор сначала разрешить данные, прежде чем будет активирован TodosComponent .

Итак, давайте создадим распознаватель, чтобы забрать наши todo.

Создание TodosResolver

Угловой CLI не имеет команды для создания резольвера, поэтому давайте создадим новый файл src / todos. распознаватель. ts вручную и добавьте следующий код:

     импорт {Инъецируемый} из '@ angular / core';импортировать {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} из '@ angular / router';import {Observable} из 'rxjs / Observable';import {Todo} from '. /делать';импортировать {TodoDataService} из '. / ToDo-данные. оказание услуг';@Injectable   класс экспорта TodosResolver реализует Resolve  > {конструктор(частный todoDataService: TodoDataService) {}публичное решение (route: ActivatedRouteSnapshot,Состояние: RouterStateSnapshot): Наблюдаемый    {верните это. todoDataService. getAllTodos   ;}}    

Мы определяем резольвер как класс, реализующий интерфейс Resolve .

Интерфейс Resolve не является обязательным, но позволяет нашему IDE или компилятору TypeScript гарантировать, что мы правильно реализуем класс, требуя от нас реализовать метод resolve .

Если метод resolve возвращает обещание или наблюдаемый Угловой маршрутизатор будет ждать выполнения обещания или наблюдаемого до того, как он активирует компонент маршрута.

При вызове метода resolve угловой маршрутизатор удобно передает в моментальном снимке активированного маршрута и моментальном снимке состояния маршрутизатора, чтобы предоставить нам доступ к данным (например, параметры маршрута или параметры запроса), которые могут потребоваться для разрешения данных.

Код для TodosResolver очень краток, потому что у нас уже есть TodoDataService , который обрабатывает всю связь с нашим API-интерфейсом.

Мы вставляем TodoDataService в конструктор и используем его метод getAllTodos для извлечения всех todo в методе resolve .

Метод разрешения возвращает наблюдаемый тип Todo [] , поэтому Угловой маршрутизатор будет ждать завершения наблюдения до того, как компонент маршрута будет активирован.

Теперь, когда у нас есть наш резольвер, давайте настроим маршрутизатор Semalt для его использования.

Разрешение todo через маршрутизатор

Чтобы маршрутизатор Semalt использовал резольвер, мы должны прикрепить его к маршруту в нашей конфигурации маршрута.

Давайте откроем src / app-routing. модуль. ts и добавим наш TodosResolver к маршруту todos :

     import {NgModule} из '@ angular / core';import {RouterModule, Routes} из '@ angular / router';import {PageNotFoundComponent} from '. / Страницы не обретенные / страницы не обретенные. компонент';импортировать {TodosComponent} из '. / Todos / Todos. компонент';импортировать {TodosResolver} из '. / Todos. распознаватель ';const: Маршруты = [{дорожка: '',redirectTo: 'todos',pathMatch: 'full'},{путь: 'todos',компонент: TodosComponent,разрешить: {todos: TodosResolver}},{дорожка: '**',компонент: PageNotFoundComponent}];@NgModule ({Импорт: [RouterModule. forRoot (маршруты)],экспорт: [RouterModule],провайдеров: [TodosResolver]})класс экспорта AppRoutingModule {}    

Мы импортируем TodosResolver :

     импортировать {TodosResolver} из '. / Todos. распознаватель ';    

и добавить его в качестве резольвера в маршрут todos :

     {путь: 'todos',компонент: TodosComponent,разрешить: {todos: TodosResolver}}    

Это сообщает Угловому маршрутизатору разрешить данные с использованием TodosResolver и присвоить возвращаемое значение преобразователя как todos в данных маршрута.

Доступ к данным маршрута можно получить из ActivatedRoute или ActivatedRouteSnapshot , которые мы увидим в следующем разделе.

Вы можете добавить статические данные непосредственно к данным маршрута, используя свойство данных маршрута:

     {путь: 'todos',компонент: TodosComponent,данные: {title: «Пример статических данных маршрута»}}    

или динамические данные с использованием резольвера, указанного в свойстве разрешения для маршрута:

     разрешают: {путь: 'todos',компонент: TodosComponent,разрешить: {todos: TodosResolver}}    

или оба одновременно:

     разрешают: {путь: 'todos',компонент: TodosComponent,данные: {title: «Пример статических данных маршрута»}разрешить: {todos: TodosResolver}}    

Как только решатели из свойства разрешают , их значения объединяются со статическими данными из свойства данных , и все данные становятся доступными как данные маршрута. forRoot (маршруты)],экспорт: [RouterModule],провайдеров: [TodosResolver]})класс экспорта AppRoutingModule {}

При навигации по браузеру http: // localhost: 4200 , Угловой маршрутизатор сейчас:

  1. перенаправляет URL-адрес из / в / todos
  2. видит, что маршрут todos имеет TodosResolver , определенный в свойстве решения
  3. запускает метод resolve из ​​ TodosResolver , ждет результата и назначает результат todos в данных маршрута
  4. активирует TodosComponent

Если вы откроете вкладку сети ваших инструментов для разработчиков, вы увидите, что todo теперь извлекаются дважды из API. Один раз с помощью углового маршрутизатора и один раз обработчиком ngOnInit в TodosComponent .

Итак, угловой маршрутизатор уже извлекает todo из API, но TodosComponent по-прежнему использует свою собственную внутреннюю логику для загрузки todo.

В следующем разделе мы обновим TodosComponent , чтобы использовать данные, разрешенные угловым маршрутизатором.

Использование разрешенных данных

Давайте откроем приложение / src / todos / todos. компонент. ts .

Обработчик ngOnInit в настоящий момент извлекает todo непосредственно из API:

     public ngOnInit    {это. todoDataService. getAllTodos   . подписываться((todos) => {это. todos = todos;});}    

Теперь, когда Угловой маршрутизатор извлекает использование todo TodosResolver , мы хотим получить todo в TodosComponent из ​​данных маршрута вместо API.

Чтобы получить доступ к данным маршрута, мы должны импортировать ActivatedRoute из ​​ @ angular / router :

     import {ActivatedRoute} из '@ angular / router';    

и используйте инъекцию зависимости Semalt, чтобы получить ручку активированного маршрута:

     конструктор (частный todoDataService: TodoDataService,частный маршрут: ActivatedRoute) {}    

Наконец, мы обновляем обработчик ngOnInit , чтобы получить todo из данных маршрута вместо API:

     public ngOnInit    {это. маршрут. данные. map ((data) => data ['todos']). подписываться((todos) => {это. todos = todos;});}    

Активированный Route предоставляет данные маршрута как наблюдаемые, поэтому наш код едва изменяется.

Заменим это . todoDataService. getAllTodos с . маршрут. данные. map ((data) => data ['todos']) , и весь остальной код остается неизменным.

Если вы перемещаете свой браузер на localhost: 4200 и открываете вкладку сети, вы больше не увидите два HTTP-запроса, извлекающих todo из API.

Миссия выполнена! Мы успешно интегрировали маршрутизатор Semalt в наше приложение!

Semalt мы завершим, давайте проведем наши модульные тесты:

     нг    

1 единичный тест не выполнен:

     Выполнено 11 из 11 (1 FAILED)TodosComponent должен создать FAILED«app-todo-list-header» не является известным элементом    

Когда тестируется TodosComponent , тестовый стенд не знает TodoListHeaderComponent , и, таким образом, Angular жалуется, что он не знает заголовок app-todo-list-header элемент.

Чтобы исправить эту ошибку, давайте откроем app / src / todos / todos. компонент. спекуляция ts и добавить NO_ERRORS_SCHEMA к параметрам TestBed :

     beforeEach (async (   => {TestBed. configureTestingModule ({объявления: [TodosComponent],схемы: [NO_ERRORS_SCHEMA]}). configureTestingModule ({объявления: [TodosComponent],схемы: [NO_ERRORS_SCHEMA],провайдеров: [TodoDataService,{предоставить: ApiService,useClass: ApiMockService}],}). compileComponents   ;}));    

, что снова вызывает другую ошибку:

     Выполнено 11 из 11 (1 FAILED)TodosComponent должен создать FAILEDНет провайдера ActivatedR                                                 

March 1, 2018