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

Что такое директива?

Директива позволяет вам прикреплять поведение к элементам DOM. Это поведение может быть сколь угодно простым или сложным .*ngFor и *ngIf являются примерами встроенных директив в Angular. В этой статье я покажу вам, как создать настраиваемую директиву автозаполнения Google Place, которую вы можете прикрепить к любому текстовому вводу.

Прежде чем мы начнем…

Чтобы использовать API автозаполнения Google Places, нам понадобится ключ API. Для получения ключа API перейдите на Платформу Google Maps и создайте новый проект.

После регистрации вы сможете найти свой ключ API в консоли разработчика. Запишите этот ключ API на будущее.

Настройка Angular проекта

Установите Node.js® и npm, если их еще нет на вашем компьютере. Теперь установите Angular CLI глобально, используя ..

npm i -g @angular/cli

Как только это будет сделано, давайте создадим новый проект Angular с помощью следующей команды:

ng new google-places-example

Теперь перейдите в каталог вашего проекта и запустите сервер разработки Angular:

cd google-places-example
ng serve

Если вы перейдете на сервер, работающий с http://localhost:4200, вы увидите экран, показанный выше.

Отлично! Теперь давайте создадим поле ввода, к которому мы будем прикреплять директиву Angular. Откройте проект Angular в вашем любимом текстовом редакторе и откройте файл src/app/app.component.html.

Измените содержимое файла на следующее

Теперь давайте добавим немного стиля, чтобы наше поле ввода выглядело красиво. Измените свой src/app/app.component.css на следующий

После этого, если вы проверите свой сервер разработки по адресу http://localhost:4200, вы должны увидеть что-то вроде этого.

Красиво, но «приложение» - довольно скучное название для нашего приложения: D. Дадим ему более информативное имя. Откройте src/app/app.component.ts и измените переменную title на все, что хотите. Я назову свое приложение «Места».

Круто, теперь давайте начнем с директивы.

Создание директивы с использованием Angular CLI

ng g d google-places

Здесь «g» - это сокращение от «генерировать», а «d» - от «директивы». Это должно сгенерировать два файла в src/app с именами google-places.directive.ts и google-places.directive.spec.ts. Все файлы, заканчивающиеся на spec.ts, являются контейнерами для написания модульных тестов.

Изменить - 01.08.2018:

Чтобы получить декларации TypeScript для Google Maps API, мы можем добавить зависимость dev следующим образом:

npm i --save-dev @types/googlemaps

Мы можем использовать это, чтобы получить интерфейсы машинописного текста, чтобы вы не получали ошибок линтера. :)

Когда мы помещаем директиву в элемент, мы получаем доступ к ссылке на этот элемент в нашей директиве. Мы будем использовать эту ссылку, чтобы прикрепить функцию автозаполнения к элементу ввода. Теперь измените google-places.directive.ts на следующее

Обратите внимание, что я изменил имя selector, так как я не поклонник автоматически сгенерированного. Здесь мы получаем доступ к ElementRef, доступному нам через конструктор, и сохраняем свойство nativeElement в переменной, чтобы мы могли передать его конструктору автозаполнения Google Places. Когда вы закончите, вам нужно изменить index.html, находящийся в src папке вашего проекта, чтобы добавить скрипт Google Places. Поместите следующий скрипт между тегом <head>.

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places" async defer></script>

Замените YOUR_API_KEY на ключ API, который вы записали ранее. Затем перезапустите сервер разработки Angular.

Теперь нам нужно добавить директиву в наш входной тег. Измените input в src/app/app.component.html на следующее

<input
google-place
type="text"
class="google-place-input"
placeholder="Type to search..">

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

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

Отправка событий из директивы

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

Измените свой google-places.directive.ts вот так

Здесь мы сделали две вещи:

  1. Мы создали функцию getFormattedAddress, которая принимает объект Google Place в качестве аргумента и анализирует его, чтобы создать полезный объект адреса.
  2. Мы добавили прослушиватель событий в API автозаполнения, который будет срабатывать каждый раз при изменении места, и мы используем этот прослушиватель событий для генерации нашего собственного события, которое будет анализировать объект места, используя указанное выше getFormattedAddress, и отправлять полученный объект адреса обратно в элемент ввода.

Мы выставили это событие через onSelect эмиттер событий. Теперь давайте воспользуемся этим эмиттером событий в нашем вводе.

Измените src/app/app.component.ts на следующее:

Мы создали функцию с именем setAddress, которую мы будем вызывать каждый раз, когда эмиттер событий выдает новое значение. Мы сохраним полученный объект и его ключи, чтобы отобразить его обратно пользователю. Теперь давайте изменим app.component.html, чтобы обработать событие и отобразить результат:

Проверьте сервер разработки и теперь мы увидим следующий результат:

Потрясающие! Мы создали нашу собственную настраиваемую директиву google-place, которая может обеспечивать автозаполнение для любого поля ввода и выдавать отформатированный адресный объект из поля ввода.

Вы можете найти этот проект Angular в моем репозитории на GitHub. Спасибо за прочтение!