Angular2 — Angular 2 Router


Содержание

Stepan Suvorov Blog

Release 2.0

Концептуальный разбор маршрутизатора Angular2 с примерами

  • подключение и базовая настройка
    • use hash
  • стейты (states)
  • специальные директивы роутера
  • параметры стейта
  • параметры запроса(query params)
  • статические параметры стейта
  • перенаправление на другой стейт
  • события (events)
  • хуки (guards)
  • резолв асинхронных данных
  • вложенные стейты (nested states)
  • множественные вью (multiple views)
  • ленивая загрузка (lazy loading)

Подключение и базовая настройка

Для использования маршрутизатора нам необходимо в первую очередь импортировать его модуль:

и прописать в зависимостях:

После чего мы можем настроить состояния(стейты). Добавим корневой стейт:

синтаксис, как вы видите, довольно простой. Нам достаточно указать путь и компонент, который будет отображаться по этому пути. Можем таким же способом добавить еще один стейт:

Теперь, чтобы подключить описание стейтов к модулю роутера сделаем:

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

Специальные директивы роутера

RouterOutlet – для задание места вывода представления:

RouterLink – хелпер для удобного вывода ссылки:

RouterLinkActive – для выделения(задания специального css класса) активных(указывающих на текущий стейт) ссылок:

также можно задавать параметр

Параметры стейта

Определяем параметр в настройках стейта:

Получаем этот параметр с помощью специального сервиса ActivatedRoute:

также можно подписаться на конкретный параметр с помощью метода pluck:

Параметры запроса(query params)

Кроме параметров стейта, можем также добавлять в url произвольное количество параметров запроса:

либо если изменяем стейт с помощью метода navigate:

Чтобы получить параметры стейта подписываемся на queryParams свойство:

Cтатические параметры стейта

Стейт также можно дополнять статическими параметрами:


И получить доступ через сервис ActivatedRoute:

Перенаправление на другой стейт

Перенаправление может быть либо автоматическим (постоянный редирект) либо условным (по какому-то действию).

Чтобы сделать автоматический редирект в настройках стейта мы прописываем свойство redirectTo, где указываем стейт, на который хотим перенаправить:

обратите также внимание, что в случае path: ” мы должны указать строгую стратегию разбора URL – pathMatch: ‘full’.

Для условного перенаправления мы используем методы router.navigate() и router.navigateByUrl():

– отличие только в том, что в первом случае вы подаете как параметр набор команд, а во втором строку URL.

Cобытия роутера

Мы можем подписываться не только на данные, но и на события происходящие в роутере, в этом нам поможет сервис Router:

кроме события NavigationStart мы также можем слушать:

  • NavigationEnd
  • NavigationCancel
  • NavigationError
  • RoutesRecognized

Хуки (guards)

На ряду с событиями в роутере есть хуки(guards), которые в отличие от событий выполняются ДО действия и в данном случае мы можем вклиниться в поток выполнения, и если нужно остановить выполнение события.

Существуют следующие хуки:

CanActivate – определяет возможность загрузки стейта

CanActivateChild – аналогично предыдущего только для вложенного стейта

CanDeactivate – запускается при смене стейта, хорошим примером будет подтверждение не сохраненных данных перед уходом со страницы:

CanLoad – определяет может ли стейт быть загружен асинхронно

Resolve – для резолвинга данных до загрузки стейта (см. отдельный пункт о резолвинге данных)

Для реализации хука нам нужно 2 момента: определить его в стейте:

и создать сам хук-сервис, который будет реализовывать соотвествующий интерфейс:

В методе canActivate мы можем возвращать как просто булевое значение, так и асинхронные Promise и Observable.

Резолвинг асинхронных данных

Для подгрузки асинхронных данных до загрузки стейта также используется хук – Resolve:

теперь создадим резолв-сервис:

и можно будет подписаться на эти данные, также как и на статические:

Вложенные стейты (nested states)

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

синтаксис вложенных стейтов идентичен основным. Вложенные стейты также могут иметь свои вложенные.

Множественные вью (multiple views)

Роутер ангуляра поддерживает множественные вью, то есть наличие нескольких именованных RouterOutlet компонентов:

Неименованный – основной. Теперь для настройки прописываем специальное свойство outlet:

Ссылка routerLink будет выглядеть для такого случая следующим образом:

а если мы хотим деактивировать второстепенный аутлет:

Ленивая загрузка (lazy loading)

Роутер также дает нам возможность организовать отложенную(ленивую) загрузку модулей. Для этого нам необходимо прописать в стейт специальное свойство loadChildren и указать в нем путь и имя модуля, который собираемся загрузить:

и инициализировать RouterModule внутри LazyModule:

мы можем определить сколько захотим состояний для LazyModule, но я для простоты определил один, который загрузит компонент AdminComponent.

Angular 2 Router Example


Use the Angular router to navigate between components when the user clicks a link. We take a look at routerLink , routerLinkActive , and more.

The Application

This is the simple demo application we will be using. We’ll see how the router manages the contents of the colored area whenever a link is clicked. Go ahead, give it a try.

The Menu

First let’s take a look at our menu. The routerLink directive on the anchor element is bound to a string containing the path of a route. We see how the router handles these paths in the next section.

We also include a element in the template. This is where the content is rendered by the router when a particular route is selected. So when the user clicks one of the links, or types the path in the address bar (e.g. http://example.com#/green ), the router will output the appropriate content in .

Also, routerLinkActive adds the CSS class in quotes to the anchor element when the route is active, effectively disabling the link.

Routes

Next we configure the router to handle the red , green and blue paths that we specified in the routerLink directives in our menu.

To do this, we build an array of objects which map our paths to a particular component. We include a redirectTo entry which provides a default route by redirecting to /green when the path is empty.

This array is then passed into the forRoot method of RouterModule . The return value from this method is exported so that we can include it in our module.

NgModule

Our route definitions are added to the module by including the routing variable in the imports property of the @NgModule directive.

HashLocationStrategy is a LocationStrategy which tells Angular to represent its state in the hash fragment of the browser’s URL, for example http://example.com#/red . This overrides the default of PathLocationStrategy which produces a URL like this: http://example.com/red .

Summary

So when the user clicks one of the links in the menu, the router will map the path to a component, and render the view in . When a route is active, routerLinkActive disables the link by adding the disabled class to the element

Where Next?

To find out more about Angular and TypeScript, check out these tutorials.

  • Hello World — Implement a super-simple custom element using an Angular and TypeScript.
  • The Angular with TypeScript Tutorial — includes examples of components, template syntax, property binding, event binding, bootstrapping and more.
  • Configuration — Configure Angular and TypeScript to download dependencies from node modules or a CDN, and to compile the TypeScript during development or in the browser at runtime.
  • Templates — introduction to inline and external templates.
  • Interpolation — use curly braces and template expressions to output data on the page.
  • Property Binding — bind to DOM properties using square brackets and template expressions.
  • Event Binding — handle DOM events using parentheses and template statements.
  • Two-way Binding — combine property and event binding to create two-way binding with ngModel .
  • Input Binding — bind to fields such as text , textarea , checkbox , radio and select .
  • Built-in Directives — see how to use built-in directives ngIf , ngSwitch , ngFor , ngClass and ngStyle .
  • Component Input Output — use @Input and @Output to pass data in to and out of a component.
  • Nested Child Routes — An example of how child routes allow navigation between multiple views when a user clicks a link in a sub-menu.

Порог вхождения в Angular 2 — теория и практика

Добрый день, дорогие хабра: жители, читатели, писатели, негативно-комментаторы.

В качестве вводной части и чтобы снять некоторые вопросы немного расскажу о себе. Меня зовут Тамара. Оужас, я девушка! Кого это пугает — закрывайте статью и не читайте.

Для остальных: у меня за плечам незаконченный лет 10 назад МИРЭА, факультет кибернетики. Но все эти 10 лет практики сложились таким образом, что по большей части я занималась рекламой и в перерывах случалось работать в различных стартапах, связанных с интернетом и не только.

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

Я покривлю душой, если скажу, что я не могу разобраться в чужом коде. Могу, на java и php могу даже какие-то простые вещи поправить. Но дальше этого мой опыт программирования никогда не уходил.

Но это же все не то, душа просила поэзии с чистого листа. И вот прекратив на некоторое время свою трудовую деятельность и взяв длительный отпуск для души и тела я таки решила попробовать что-то сделать с 0 и самостоятельно. Под «что-то» я понимаю свой маленький проект.

Когда думала и выбирала на чем делать, то для бэкенда остановилась на PHP. А точнее на фреймворке — Laravel.
На нем я остановилась по той причине, что для меня он показался самым низким по порогу вхождения. Мне не нравится в нем документация, так как с моей точки зрения многие моменты не раскрыты и приходится лезть в исходники, чтобы почитать комментарии. Но основные общие моменты разобраны на многих ресурсах. Laracasts как источник обучения весьма грустен. Тейлор там рассматривает все достаточно поверхностно, перескакивая с одного на другое и совершенно не углубляясь. Все по верхам.

Для фронтенда я выбрала Angular 2. Да, я знаю, что он в beta-режиме :), но мне он опять же показался логичным.
Для въезжания в Angular2 я пользуюсь их документацией, исходниками на github, чтения issue там же, stackoverflow — но там как-то все сейчас грустно — задают вопросы в основном ответы на которые есть в документации.

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

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

Настройка Angular 2 и Laravel.

Я не буду заострять на этом внимание. Для Angular 2 — вся базовая настройка проекта написана в их 5-и минутном туториале HelloWorld.
С Laravel тоже базовое создание проекта описано в документации.

Остановлюсь поподробнее только на том моменте, который меня на старте поставили в тупик.

Когда я начинала проект меня волновал вопрос взаимодействия этих товарищей в плане роутинга. А именно, если грузить Angular в папку public, то у меня лично возникли проблемы с роутингом. Так как у Laravel свой роутинг, который с роутингом Angular у меня вообще никак не совпадал, а манипуляции c отдачей нужных роутов не привели к нужному результату. При возврате через браузер на предыдущую страницу мне постоянно выбрасывалась laravelевская страница с ошибкой. Убив пару часов, чтобы подружить этих товарищей я приняла решение разнести по разным доменам api(бэкенд) и фронтенд. Как по мне, так в случае замены одной или другой части целого я не буду зависеть от незаменяемой части.
Так, что, условно сейчас я имею два проекта. Один, условно, крутится на домене: api.proect.dev , а второй на: proect.dev

Вдогонку автор sanex3339 подсказал как можно пробросить роуты Angular 2 через роутер Laravel 5.
За что ему огромное человеческое спасибо!
Теперь имеем два рабочих решения, из которых можно выбирать: разносить по доменам и разделять и властвовать, или компактно упаковать все в одном.

Так как я все-таки заявила в заголовке, про порог вхождения именно в Angular, то я не буду подробно останавливаться на API.

Цукерберг рекомендует:  Выскальзывающая панель на CSS

Быстренько сделаем бэкенд

Если коротко, то наша работа во фронтенде будет по 2 запросам к бэкенду. По одному запросу мы получаем данные из таблицы, по второму мы туда их записываем :) Элементарно, Ватсон :)
Далее я просто приведу куски кода бэкенда с комментариями в самом же коде, чтобы нам дальше двигаться.

php artisan make:model MainCategory -m

Эта команда создаст нам модель MainСategory и миграцию для этой модели.
В миграцию вставляем нужные нам строчки.

2020_02_22_135455_create_main_categories_table.php


MainCategory.php

Ну и собственно контроллер, который со стороны php будет определять в каком виде данные получать, как их из базы вытаскивать, как запихивать их обратно. Он создается командой php artisan make:controller MainCategoryController
У меня он лежит в своей папочке с названием Catalog, обращаю на это внимание, так как дальше в роутах он обязательно проскользнет.
Так, как чтобы со стороны бэкенда не плодить ненужны папки-подпапки я решила, что в тематическом контроллере под разными названиями плодить нужные мне запросы :)

MainCategoryController.php

Ну и последнее, что осталось сделать — это прописать пути. Вот кусочек route.php и 2 пути по которым мы и будем запрашивать нужную нам информацию.

На выходе мы на самом деле получаем 2 ссылки:

На этом миссия по настройке бэкенд завершена.

Ура! Обещанный Angular 2.

Ну теперь начинается самое интересное.
Так как я пока еще не определилась окончательно со структурой в самом проекте и что и как на страницах буду отображать, то вот скрин того, как это сейчас у меня выглядит. Единственное, что для habra я кусочки шаблонов внесу в сами .ts скрипты, хотя у меня они сейчас вынесены в отдельные html.

Как я уже говорила — за исходник я брала базовую конфигурация из туториала. Поэтому тут ничего особенного нет. Ну, кроме, что main.ts я переименовала для себя в boot.ts :)

index.html
Единственное, на что здесь стоит обратить внимание, так это на то, что к базовым скриптам добавлены

Без этих товарищей не будут работать роуты и запросы-ответы к API.

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

Роуты у меня расположены в app.component.ts . И, соответственно он же у меня является тем самым входным компонентом, который и видно в виде тэгов на главной странице.

Собственно, чтобы роуты заработали нам осталось всего-ничего — добавить соответствующие компоненты: HomePageComponent и DashboardMainCategoryComponent .

Так, сделали. Теперь надо пойти в boot.ts и импортировать основной компонент ShopAppComponent .

boot.ts
Это самый пустой компонент в моем проекте :) У меня он ничего не делает, кроме как загружает все, что нужно из основного компонента с названием app.component.ts

На этом с роутами мы закончили. И, если сейчас сделать npm run start , то у вас уже будет сайт на котором можно попрыгать между двумя страничками.

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

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

Базовая модель MainCategory

Перво-наперво нам надо сделать простой класс — аналог Модели на php, pojo — на java.
Давайте его обзовем аутентично: main-category.ts

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

Может возникнуть вопрос — почему даты у меня как string. Скажу честно — у меня был косяк с тем, чтобы запрашивать даты как даты. Постоянно выдавало ошибку, поэтому я пока отоложила ломание головы и пошла по простому пути.

MainCategoryService

Ладно, первый шаг сделали. Потопали дальше. Если заглянуть в ARCHITECTURE OVERVIEW Angular2, там они предлагают придерживаться той идеи, что ту часть приложения, которая что-то делает (например, авторизация, логгирование, калькулятор пошлины или, как в нашем случае — общение по API) надо называть service и выносить в отдельный файл, который мы потом будем импортировать туда, куда надо. Это необязательно, но желательно. Я так и поступила. Отсюда у меня появился main-category.service.ts

На этом основное взаимодействие с сервером мы описали. Осталась сущая ерунда — пара компонентов и дело в шляпе!

GetMainCategories

Начнем с компонента, который получает данные: main-category.get.component.ts

PostMainCategory

В Angular2 есть два способа создания форм — template и data-driven. Принципиальное отличие у них в том, что в template — все проверки пишутся в самом шаблоне. Т.е. это более близко к Angular1. Data-driven — это нововведение в Angular2 и все проверки уходят из шаблона. Ну это пока то как я для себя поняла эту разницу. Боюсь, что тему я до конца не раскрыла, так как в голове по поводу этих форм еще каша. Честно сказать — второй вариант с формами мне показался проще и чище. Но с ним есть сейчас много своих косяков.

К сожалению radiobutton пока шалит в Angular2 и работать может, но только после длительных плясок с бубном, так, что для своих нужд я остановилась пока на checkbox.

Осталось все нужное импортировать в наш класс DashboardMainCategoryComponent . Теперь он будет выглядеть вот так:

На этом мы имеем простое приложение с получением и отправкой данных на сервер.

Итоги

Если взять чистое время, которое у меня заняло написать то, что я выложила выше и заставить это работать:
Backend — 1 час 17 минут. Это не совсем чистое время, а вместе с загрузкой PhpStorm, хождениями на перекуры и отвлечениями на телефонные разговоры. Для меня это достаточно просто, так как все таки php я не первый раз вижу.
С Angular2 все сложнее.
Я никогда не копалась в JS. Нет, скриптик подключить я могла по инструкции, а вот дальше — для меня это был темный лес, в который я нос не совала. В итоге на курение доков по Angular2, JavaScript, TypeScript, вникание, написание, перепроверки, переделки у меня ушло чистых 12 часов 48 минут. Перекуры, разговоры, загрузки-перезагрузки IDE в этом времени не учтены.

Итого: IMHO Angular2 весьма опасен тем, что туда могут вот так вот, достаточно просто влезть такие блондинки как я, и даже потратив не так много времени сделать что-то большее, чем HelloWorld или же ToDo-список.

P.S. Тема статьи родилась из прочтения одного твита, где задавали вопрос — насколько высок порог вхождения в Angular2. Ну что же, можно сказать, что невысок. Все гуру могут хвататься за голову и предрекать наступление краха из-за того, что скоро полезут недоучки, которые будут писать полную ерунду, а им потом разгребать это.

P.P.S. За орфографию, грамматику, стилистику, некоторую саркастичность заранее прошу прощения, а при указании на что-то из первых трех пунктов — исправлю это :)

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

И огромное вам спасибо, если дочитали этот пост!


Angular роутинг — обработка route параметров в версии v2+

Дата публикации: 2020-10-28

От автора: продолжаем изучать, как работает в Angular роутинг. Роутер Angular – очень мощный инструмент, позволяющий делать все, что связано с роутингом. С его помощью можно: обрабатывать базовый роутинг, защищать роуты с помощью guard, лениво загружать приложение, и многое другое.

Одна из наиболее стандартных задач роутера – создавать роуты с параметрами. Например, на сайте Scotch ссылки на профиль пользователя выглядят так https://scotch.io/@chris. Chris – это динамический параметр роута.

2 способа получения параметров роута

Роутер позволяет вытягивать параметры роута разными способами. Обсудим оба способа и поговорим об их преимуществах и недостатках:

Снимок: роутер позволяет делать снимок текущего роута

Observable/Stream: Angular активно использует Observables, а значит, роутер возвращает Observables, который мы можем поджидать

Практический курс по созданию веб-приложения на Angular4

Скачайте БЕСПЛАТНЫЙ мини-курс и изучите базовые возможности JavaScript-фреймворка Angular 4 за ближайшие 3 дня

Поговорим об этих способах более подробно немного позже.

Создание роутов с параметрами

Давайте разберем простой пример. Мы создадим роут с параметрами.

Обратите внимание: это код из AppRoutingModule, который Angular CLI создает по умолчанию при запуске команды ng new my-app –routing. Параметр создается через синтаксис двоеточия. У нашего роута есть параметр :username.

Ссылки на роуты с параметрами

Нам необходимо создать роуты на обе секции. Ниже представлено несколько способов, как можно сослаться на домашнюю страницу. В Angular роутере есть директива RouterLink. Код ниже делает то же самое.

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

Ссылка на страницу профиля с помощью параметров роута

Вот так можно ссылаться на профили пользователей. В сценарии ниже у нас есть переменная username в классе компонента.

Мы создали ссылки. Теперь можно перейти к получению параметров роута в UserComponent.

Получение параметров роута (снимок)

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

Базовая настройка UserComponent.

Практический курс по созданию веб-приложения на Angular4

Скачайте БЕСПЛАТНЫЙ мини-курс и изучите базовые возможности JavaScript-фреймворка Angular 4 за ближайшие 3 дня

Мы вставим ActivatedRoute в этот компонент через конструктор. Далее с помощью ActivatedRoute мы вытянем username параметр роута в ngOnInit().

Для получения username больше ничего не нужно! Давайте разберем следующий способ получения параметров роута, а также узнаем, почему второй метод лучше.

Производительность роутов Angular

Angular всеми силами старается поддерживать максимальную производительность приложения. Один из способов – повторное использование компонентов по максимуму. Angular не обязательно уничтожать и создавать компоненты заново, он может просто переключаться между данными.

«Angular повторно использует компоненты для повышения производительности»

Сценарий для которого не подходит снимок – мы находимся на странице одного профиля и переходим по ссылке на другой. Снимок запускается лишь раз при инициализации компонента. При перемещении из /users/chris в /users/nick компонент не обновляется.

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

Получение параметров роута (observable)

Observable по своей натуре представляют поток событий. То есть когда мы переходим от профиля к проофилю, вместе с новыми данными будет передаваться observable.

В роутере Angular v4+ есть ParamMap – Observable, который мы можем использовать. Синтаксис использования:

# 7 Angular2. Тур героев. Роутинг. Часть 1

Всем привет. Мы продолжаем «Тур Героев». В этом уроке мы добавим страницу Dashboard, прикрутим роутинг и реализуем навигацию между дашбоардом и списком героев.

Первое, что мы сделаем, это порефакторим наш AppComponent. Сейчас он отрисовывает список героев. Мы же хотим, чтобы наш AppComponent отвечал только за навигацию по страницам. Поэтому давайте перенесем отрисовку списка героев в другой компонент.

Давайте переименуем наш app.component.ts в heroes.component.ts и переименуем внутри него класс AppComponent на HeroesComponent. Теперь переименуем селектор с my-app на my-heroes.

Наш новый AppComponent будет содержать в себе ссылки навигации вверху страницы, а под ними выводить страницу, которую мы хотим отобразить в аутлете.

Давайте с вами создадим новый файл app.component.ts. Опишем класс AppComponent. Он у нас пока будет пустой. Так же не забываем слово export в начале.


Создаем переменную title

Импортируем Component и описываем декоратор.

Внутри темплейта описываем тег в который мы будем выводить наших героев.

Теперь очень важный момент, о котором я говорил в прошлом уроке. Нам нужно удалить HeroService из списка провайдеров в файле heroes.component.ts так как теперь его регистрация будет в app.component.ts и мы не хотим, чтобы у нас создавалось 2 копии сервиса на 2 разных уровнях приложения. Поэтому мы удаляем HeroProviders из списка провайдеров в heroes.component.ts

Также нужно не забыть добавить в app.component.ts директивы HeroesComponent, которая будет отрисовывать у нас список героев и наш провайдер HeroService.

Теперь нужно не забыть их импортировать.

Теперь у нас есть все, что нам необходимо для работы. Также мы можем удалить наш title из шаблона heroes.component.ts и переменную title из класса HeroesComponent.

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

Теперь давайте реализуем роутинг.

Первое, что нам нужно сделать, это добавить тег base в index.html

Это нужно делать по двум причинам. Во первых, только так у нас будет работать pushState для изменения урла, иначе ангулар у нас будет материться на то, что мы не добавили base href. Во вторых, браузеру нужен base href для того, чтобы строить относительные ссылки к css, скриптам и картинкам.

Также нужно добавить router.js в подключение скриптов в index.html

Цукерберг рекомендует:  Pascal - задача на Pascal

Роутер в angular 2 — это сервис. Мы можем его импортировать и добавить в список провайдеров, чтобы начать его использовать. Роутер состоит из сервисов, директив и конфига. Давайте все это импортируем.

Что это такое? RouteConfig — это конфиг роутера, ROUTER_DIRECTIVES — это набор директив для роутера, и ROUTER_PROVIDERS — это провайдеры для роутера.

Для начала добавим в directives и providers импортированые сервисы и директивы.

Как вы видите мы удалили HeroesComponent из списка directives. Это потому, что AppComponent больше не будет отрисовывать компонент героев. Это будет делать роутер.

Теперь давайте добавим конфиг нашего роутера.

RouteConfig принимает массив обьектов. В каждом обьекте у нас есть path — путь при котором будет срабатывать роут, name — оффициальное имя роута, которое всегда должно начинаться с большой буквы и компонент — который будет отрисовываться когда мы будет переходить на этот роут.

Теперь нам нужно задать в шаблоне место, куда этот компонент будет выводиться. Для этого воспользуемся директивой роутера . Он позволяет выводить в это место компонент, описаный в конфиге роутера.

Если мы перейдем на урл /heroes, то увидим, что у нас отрисовались наши герои.

Теперь давайте добавим в шаблон ссылку для перехода на урл с списком героев.

Мы применяем RouterLink директиву, а это еще одна директива ROUTER_DIRECTIVES. У тега а мы просто указываем атрибут с именем Heroes. Это как раз имя, которое мы определили в RouteConfig.

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

Давайте добавим теперь еще одну страницу. И это будет страница Dashboard. Для этого создадим файл dashboard.component.ts с таким кодом.

Импортируем DashboardComponent в AppComponent.

Теперь добавим еще 1 роут в RouteConfig.

Единственно, что тут появилось нового — это useAsDefault переменная. Она указывает какой роут нужно применять для рутовой страницы.

Давайте добавим ссылку на dashboard и обрамим их в nav тег.

Теперь в браузере мы можем переходить между страницами и все работает.

Пробрасываем роуты Angular 2 через роутер Laravel 5

После прочтения статьи «Порог вхождения в Angular 2 — теория и практика» у меня появилось желание показать, как можно пробросить все роуты Angular 2 через роутер Laravel 5.

Идея следующая

  • в директории resources/views/backend будет лежать представление, являющееся точкой входа для всех роутов Angular 2. Для каждого роута Angular 2, роутер Laravel 5 будет нас перенаправлять на это представление;
  • под каждый Angular 2 роут в директиве @RouteConfig нам придется создать копию в роутере Laravel;
  • все роуты Angular 2, по которым подтягиваются шаблоны, будут иметь вид вида /templates/SomeComponent.main , и будут запрашиваться роутером Laravel 5 по пути вида resources/views/frontend/SomeComponent/main.blade.php

Приступим

Чтобы не запутаться, разобьем все представления в директории resources/views на 2 подпапки:

  • backend — для представлений, которые Laravel 5 использует напрямую;
  • frontend (в статье будет использоваться frontend , но кто-то пожелает переименовать, например в templates ) — для всех шаблонов, которые будут использоваться в Angular 2.

1) Front-end

Допустим, у нас есть уже созданный root-компонент app.component.ts , а так же 2 компонента: components/MainComponent.ts , который будет загружаться по умолчанию, и components/EditComponent.ts .

Мы хотим указать в директиве @RouteConfig 2 роута: один ‘/’ с именем Home , ведущий на MainComponent , а второй ‘/edit’ с именем Edit , ведущий на EditComponent .

Далее необходимо задать для компонентов их шаблоны:


2) Back-end

Первым делом, в роутере Laravel 5 продублируем все основные роуты Angular 2. Все подобные роуты мы будем направлять в AngularRoutesController .

В AngularRoutesController мы будем просто рендерить представление, являющееся точкой входа, для Angular 2:

Представление views/backend/content.blade.php должно содержать в себе тег, в который будет грузиться Angular 2 приложение, у нас это app .

Для роутов Angular 2, ведущих к темплейтам, создадим еще 1 Laravel 5 маршрут, который будет перенаправлять запрос на контроллер AngularTemplatesController :

Внутри AngularTemplatesController нам необходимо добавить к $template , в котором содержится часть пути к представлению с шаблоном, имя нашей папки с шаблонами Angular 2 — frontend .

В результате, все Angular 2 шаблоны, которые будут запрашиваться по URL-адресу вида /templates/SomeComponent.main будут браться по пути вида resources/views/frontend/SomeComponent/main.blade.php . Мы сможем использовать шаблонизатор Blade в шаблонах Angular 2.

Нюансы

Поскольку в шаблонизаторе Blade и в шаблонах Angular 2 используется одинаковый синтаксис с двойными фигурными скобками << . >> , для корректной обработки двойных фигурных скобок, относящихся к Angular 2, необходимо будет ставить перед ними символ @ .
Этот символ позволит шаблонизатору Blade игнорировать такие конструкции, для последующего из разбора Angular 2.

Angular2 близко

Ну, на самом деле не очень…

Angular, наверно, самый популярный js-фрэймворк. По крайней мере, ни один холивар без его упоминания не обходится. И как мы все уже знаем, готовится к выходу вторая версия данного фрэймворка. Которая, по сути, будет являться другим инструментом, предназначенным для решения других целей. Думаю, к месту будет следующая картинка, гуляющая в сети.

Но пока это только абстракция. Текущее состояние нового Angular это 40-я итерация альфа версии, которая доступна уже с 9 октября. Конечно, использовать второй Angular на продукции никак нельзя, но посмотреть, что он готовит, можно. Собственно, что я и хочу показать.

Поискав несколько гайдов и туториалов по Angular 2.0, могу с уверенностью сказать, ни один из них не является рабочим — настолько серьезны изменения между итерациями. Даже «пятиминутный старт» на официальном сайте не работает при точном копировании кода и требует дополнительного внимания.

Но к радости новичков существует песочница для Angular 2.0, включающая в себя более-менее стабильную итерацию со всеми зависимостями, которые необходимы для оптимальной работы. Это 20-я итерация, которая вышла еще далекой весной и как неудивительно не содержит некоторых фишек, о которых можно прочитать в каком-нибудь мануале. Но для демонстрации, думаю, этого хватит.
Что же изменится в новом Angular по сравнению с текущей версией. Если в двух словах то это:

  1. Поддержка теневого DOM;
  2. Использование изолированных контекстов вместо scope (нечто похожее на синтаксис controllerAs, но доступное «из коробки»);
  3. Отказ от концепции описания директив в пользу создания компонентов для приложения с использованием классов и аннотаций (фишки теневого DOM).

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

Для того чтобы сравнить два практически разных фрэймворка, я решил написать одно и тоже шаблонное приложение. Это PhoneCat с официального сайта Angular версии 1.х. Переосмысление для первой версии и создание на второй.
Чтобы облегчить себе задачу, приложение, которое будет написано на первой версии, будет написано в стандарте языка 2015 года или es6, так как это один из стандартов, которые Angular 2.0 будет поддерживать «из коробки». Это говорит о том, что разработчики заменяют собственные модули Angular версии 1.х на модули языка современного стандарта.

И, собственно, вот что получилось…

Bootstrapping

Или инициализация приложения.

В Angular 2.0 пропадает всем известная директива ng-app, которая необходима для установления точки входа в приложение. Вместо этого необходимо объявить главный компонент (class App), который в свою очередь будет подтягивать остальные компоненты приложения.

После импорта всех зависимостей в главный «модуль» при помощи аннотаций Component и View мы описываем наш компонент: по какому селектору он будет доступен, и какой шаблон будет подставлен на его место. Тут же указываются зависимости всех остальных компонентов, которые будут применяться на шаблоне основного. Например, директива For или свой компонент, такой как phoneItem. В итоге, мы должны получить некоторую древовидную иерархию компонентов, которые косвенно или прямо зависят от главного. И кстати, вопрос организации данной иерархии в виде файловой структуры остается открытым, так как непонятно, как организовывать приложение. Или хранить компоненты разного уровня в иерархии приложения на одном уровне файловой системы или плодить бесконечные ветви каталогов?

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

После всех объявлений производим инициализацию приложения данной инструкцией bootstrap(App);
Стоит заметить, что инициализация приложения на Angular версии 1.х не многим отличается от второй версии, за исключением манипуляций с DOM.

Dependency Injection (DI)

Или внедрение зависимостей.

Одной из основных особенностей Angular версии 1.х это доступный «из коробки» DI, который с легкостью позволяет следовать принципу «разделяй и властвуй» при разработке приложений. Сложные сущности реального мира при переводе в программный код могут быть детерминированы и разнесены в разные модули, представленные объектами, служащими на благо всей системы. Такой подход в разы облегчает разработку и понимание концепции самого приложения. Тем более, такие системы очень легко тестировать, так как не нужно тянуть огромную цепочку зависимостей, а только лишь довольствоваться единым модулем.

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

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

Помимо этого, Angular 2.0 обладает своей уникальной особенностью в области DI. Это так называемый child injector.
Как уже говорилось, приложения на новом Angular будут выглядеть как некоторые иерархичные структуры компонентов. И что бы облегчить связь родительских компонентов с дочерними, дочерние компоненты смогут наследовать их зависимости. Причем уже сейчас есть механизм, при помощи которого происходит настройка данного наследования. Можно выбирать, какие зависимости пойдут дальше, а какие лучше оставить только на этом уровне.
Кроме всего этого, зависимости в новой версии фрэймворка также могут подгружаться асинхронно.

Впрочем, концепция внедрения зависимостей для нового Angular обширна, и о ней также можно найти много информации в сети. Стоит только сказать, что продуманность нового подхода все ближе и ближе по качеству к серверному способу организации. Как, например, в .NET или Java.

Templating

Или шаблонизация в приложениях.

Если в первой версии фрэймворка с шаблонами все ясно (мы пишем шаблон для каждого нашего условного «компонента», и они по очереди подставляются в «розетку», создавая иллюзию множества страниц), то во второй версии — это уже полноценное одностраничное приложение. Один вход – множество компонентов с независимой логикой работы. Поэтому случаи, где без директивы не обойдешься в первой версии, приходится решать по-другому во второй. Тем более в условиях отсутствия двусторонней привязки данных иногда приходится использовать костыли нестандартные и креативные решения.

На особенностях синтаксиса объявления переменных или использования циклов для повторяющихся конструкций, думаю, нет смысла останавливается. Это все легко ищется в сети.

И стоит еще сказать, как уже упоминалось, что новый Angular поддерживает теневой DOM. Это открывает новые возможности в области увеличения производительности, так как можно собирать готовые страницы на серверной части, освобождая клиентскую от размышлений.

Routing

Сейчас данных о том, как будет выглядеть в конечном итоге механизм маршрутизации, в новой версии Angular еще маловато. Но концепция использования компонентов оставляет свой отпечаток. Известно, что маршрутизация будет сильно похожа на серверный способ организации, который сейчас, например, использует Express для node.js, a именно Router.

Возможным будет создание нескольких конечных точек, они же компоненты или отдельные дочерние приложения, имеющие разные конфигурации маршрутизации. Сейчас нечто подобное можно сделать при помощи ui-router, который в своем арсенале имеет именованные ui-view, способные сымитировать «компоненты» в терминах новой версии Angular.


Directives, Services, Filters…

Как уже много раз упоминалось для второй версии, компоненты – это все. Только лишь сервисы, перекочевав, стали тем, чем, по сути, они должны были быть в первой версии. В новом Angular компоненты берут на себя практически все.
В итоге получается, что новый Angular – это тот Angular, которым должен был быть существующий. Но почему же первая версия получилась другой?

Дело в том, что, когда Angular версии 1.х был создан, почти пять лет назад, он не был предназначен для разработчиков. Это был инструмент, предназначенный больше для проектировщиков, которые должны были просто и быстро строить статический HTML. В течение долгого времени это претерпевало изменения. Разработчики прикладывали много усилий, чтобы адаптировать этот продукт к современным реалиям, постоянно обновляя его и улучшая. Делали все, чтобы постоянно оставаться «на плаву», поскольку потребности современных веб-приложений постоянно изменялись. Однако всему есть ограничения, которые существуют из-за начального непонимания назначения продукта. Много этих пределов касаются проблем исполнения и производительности. Чтобы решить эти проблемы, необходимы новые подходы и стратегии.

Angular 2 – Routing

Hope you are well. First of all thank you guys, for reading my posts and supporting me by sharing my posts on social media. In this post I will explain the concept of Routing in Angular 2.

Routing is nothing but enabling navigation to different pages of the application. Applications have become much faster (Thanks to SPA’s) and routing acts as a glue to your entire app.

The entire code of this tutorial can be found here.

A video screencast of this tutorial can be found below.

As usual, I would start from scratch and show you how Routing is done in angular 2 apps.

Цукерберг рекомендует:  21 пример красивых сайтов приложений для iPhone

Let’s get the angular-2 seed from the official site using the below command.

Navigate to the directory(angular2routing if you used the above command as it is) and give the below command.

Once this is done; Let’s go ahead and include the bootstrap-material design files in our index.html.

I have used cdn links to reference these files instead of installing them into our app for simplicity.

Now create a new file called app.component.html and add the below the code.

This will add a beautiful navbar on the top with two links namely About Us and Pricing.

Now let us go ahead and create these two pages.

create a file aboutus.html and add the below code.

Then create a aboutus.component.ts file and add the below code.

Nothing fancy, I have just created an array and then used ngFor to display the elements of the array on the aboutus page. I will let you know what ROUTER_DIRECTIVES does in the later part of the is tutorial.

Now create a new file called pricing.html and add the below code.

Then create another file pricing.component.ts and add the below code.

Okay., Now we need to link these up to the Links on the navbar right ? Lets do that.

Open up index.html and below the line add the following line.

Now open up main.ts and add an import for ROUTER_PROVIDERS.

ROUTER_PROVIDERS is nothing but a constant array which has references to all the router classes. By adding this to the bootstrap method we need not import it in each and every ts file to make use of the router classes.

Get back to the app.component.ts file and write Router configurations. The app.component.ts should look as shown below.

Let me break this down.

  1. There are 3 route config lines. one for about us page, one for pricing page and one to redirect all the wildcard url patterns; i.e., when a user enters any other url other than these.
  2. The useAsDefault: true is used to set the default page when the page loads.
  3. ROUTER_DIRECTIVES is a constant array that will contain a reference to RouterOutlet and RouterLink classes which we would use here.

Now open up app.component.html file and add the selector at the very bottom as shown below.

This will indicate the place where the pages (AboutUs or Pricing) is to be loaded. Or in other words by adding this to the bottom of the app.component.html the pages will be loaded below the NavBar always.

Now you would a screen similar to the one shown below.

If you click on the pricing or About us you could see that routing works fine.

Wow.. That was quick.

Now let us see how we could pass Parameters while navigating; i.e., RouteParams.

We will make the list items on the About us page clickable. Modify the code in the aboutus.html page. It should now look as shown below.

I have just added a anchor tag which will navigate to MemberDetails component and pass an id along with it.

Now go ahead and create a memberdetails.html file as shown below.

create a memberdetails.component.ts and add the below code.

As you could see I have a button in this page which is kind of like a back button. I am simply using it along with the router class to navigate back to the AboutUs page.


Now open up app.component.ts file and modify the code as shown below.

As you can see I have added a new line in the RouterConfig which includes the url pattern along with the id.

Now if you recall (or scroll up) you would understand why we sent the id in the aboutus.html anchor tag. There I had just sent the index of the array as id. Usually its the id of the list element that you are clicking which is got from the server.

Now if you click on any of the link and see the address bar of your browser you could see as shown below.

The id 1 gets passed along with the Url. This is how you pass parameters or rather use RouteParams in Angular 2.

That’s it guys. Now we have learnt how to implement Routing in a Angular 2 App, and passing parameters.

Hope this helped you guys. Thanks for reading. Please watch the video for a better understanding.

Angular2 — Angular 2 Router

3543 просмотра

5 ответа

902 Репутация автора

В angular 1. * я использовал ui-router и смог передать NON URL Parameters из одного состояния в другое. Под NON URL Parameter я подразумеваю передачу некоторых параметров, которые НЕ появляются в URL (таким образом, полностью прозрачны для пользователя).

Способ сделать это в Angular 1. * состоял в том, чтобы определить подобное состояние (stateToRedirect — это параметр без URL)

И меняем состояние вот так:

В LOGIN_STATE я смог получить доступ к этому параметру, сделав это:

Я пытаюсь найти то же поведение для Angular 2 Router, насколько я понимаю, Angular 2 Router значительно улучшился, и нам может не понадобиться ui-router-ng2.

Итак, мой вопрос: как вы воспроизводите вышеупомянутое поведение в Angular 2 Router?

Этот вопрос, казалось, был тем, что я хотел, но я не хочу параметр в URL, и свойство «data» на маршруте кажется хорошим, но я не могу найти документацию о том, как установить его динамически.

Ответы (5)

1 плюс

163 Репутация автора

Вы должны импортировать RouterModule и Routes из @ angular / router.

Например, в вашем компоненте:

Вы можете передавать статические параметры, как это, не показывая в URL

2 плюса

561 Репутация автора

Если оба компонента принадлежат одному и тому же модулю, рассматривали ли вы вместо этого использование службы? Добавьте модель (или параметры) в службу, внедрите ее в качестве зависимости в обоих компонентах, установите ее значение в одном компоненте и получите в других компонентах.

Это возможно с помощью опции skipLocationChange

и в деталях компонент, получить его, как показано ниже

8 плюса

2173 Репутация автора

Вопрос, который вы задаете, касается скорее связи между компонентами, а не маршрутизации как таковой. Требуется передать данные из одного компонента (связанного с конкретным маршрутом) в другой компонент (связанный с другим маршрутом).

Связь между компонентами может быть достигнута следующими способами

Компоненты, имеющие отношения родитель-потомок, могут передавать данные через декораторы @Input () и @Output () и генераторы событий.

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

Через роутер. Данные могут быть переданы через маршрутизатор в качестве параметров пути , например: my/path/thisisapathvalue , необязательных параметров ( с использованием матричной записи), например , my/path;item=hello;item2=world или с помощью строки запроса paramters например my/path?item=hello&item2=world . Вы также можете разрешить данные для конкретного компонента с помощью средств защиты, которые разрешают статические данные, данные, полученные с сервера, разрешаются с помощью функций и т. Д.

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

1 плюс

58 Репутация автора

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


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

Чтобы показать вам пример

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

1 плюс

626 Репутация автора

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

Угловая документация

Пример видео с канала Angular University на YouTube (нет связи)

As with last week’s post this post is going to cover multiple topics related to while creating a contact detail page to go along with the existing contact list page that is part of the ASP.NET Basics repo, but this time using Angular 2 instead of Aurelia. The code before any changes can be found here. If you are using the sample application keep in mind all the changes in this post take place in the Angular project.

Creating a detail view and view model

Create contactdetail.component.html in ClientApp\app\components\contacts . This view that will be used to display all the details of a specific contact. It will also link back to the contact list. The following image shows the folder structure after the view and view model have been added.

The following is the full contents of the view.

*ngIf is adding/removing the associated div based on a contact being set or not.

<> is Angular’s one-way binding syntax. For more details check out the docs.

View model

For the view model add contactdetail.component.ts in the ClientApp\app\components\contacts folder which is the same folder used for the view.

Make not of the imports needed to make this view model work. To start off Contact is needed to define what the definition of a contact is and ContactService is being used to load the data for a specific contact.

Angular’s core is imported to allow the view model to set as a component using @Component decorator as well as to all implementation of OnInit lifecycle hook. Angular’s router is being used in the ngOnInit function to allow access the parameters of the route that caused the route to be triggered using this.route.params .

The switchMap operator from reactive extensions is used to map the >this.contactService.getById .

Adding get by ID to the Contact Service

The existing ContactService doesn’t provide a function to get a contact by a specific ID so one needs to be added.

The following calls the API in the Contacts project and uses the result to create an instance of a Contact as a promise which is returned to the caller.

The base URL was also moved to a class level variable so that it could be shared.

Add a route with a parameter

To add the new contact detail to the list of routes that the application handles open app.module.ts in the ClientApp/app folder. First, add an import at the top of the file for the new component.

Next, add the ContactDetailComponent to the declarations array of the @NgModule decorator.

Finally, add the new route to the RouteModule in the imports section of the @NgModule decorator.

path is the pattern used to match URLs. In addition, parameters can be used in the form of :parameterName . The above route will handle requests for http://baseurl/contact-detail/ where < >ngOnInit function of the view model route.params can be used to access route parameters.

component is used to locate the view/view model that goes with the route.

Integrating the detail view with the contact list

The contact list view and view model needed the following changes to support the contact detail page.

View model

A variable was added for the >onSelect function which takes a contact and gets called when a contact is selected. The following is the fully contact list view model.

The changes to the view model were not required to add the contact detail page, but are used show how to set up a click handler the view side. In the future, the selected contact will come in handy when the list and details were shown at the same time.

The amount of data being displayed was reduced to just ID and name. A column was added with a link to the details page. The following is the full view.

(click)=”onSelect(contact)” will cause the onSelect function of the view model to be called with the related contact when the associated element is clicked.

[routerLink]=”[‘/contact-detail’, contact.id]” use the router to create a line to the contact details page passing the contact ID as a parameter.

As a reminder of how to use a route’s parameter here is the ngOnInit function from the contact detail view model.

Wrapping up

As with the related Aurelia post, there are a lot of topics covered in this post, but they are all related to the process of adding a new page and route to the application.

The code including all the changes for this post can be found here.

Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих