В последнее время я много играл с 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
вот так
Здесь мы сделали две вещи:
- Мы создали функцию
getFormattedAddress
, которая принимает объект Google Place в качестве аргумента и анализирует его, чтобы создать полезный объект адреса. - Мы добавили прослушиватель событий в API автозаполнения, который будет срабатывать каждый раз при изменении места, и мы используем этот прослушиватель событий для генерации нашего собственного события, которое будет анализировать объект места, используя указанное выше
getFormattedAddress
, и отправлять полученный объект адреса обратно в элемент ввода.
Мы выставили это событие через onSelect
эмиттер событий. Теперь давайте воспользуемся этим эмиттером событий в нашем вводе.
Измените src/app/app.component.ts
на следующее:
Мы создали функцию с именем setAddress
, которую мы будем вызывать каждый раз, когда эмиттер событий выдает новое значение. Мы сохраним полученный объект и его ключи, чтобы отобразить его обратно пользователю. Теперь давайте изменим app.component.html
, чтобы обработать событие и отобразить результат:
Проверьте сервер разработки и теперь мы увидим следующий результат:
Потрясающие! Мы создали нашу собственную настраиваемую директиву google-place, которая может обеспечивать автозаполнение для любого поля ввода и выдавать отформатированный адресный объект из поля ввода.
Вы можете найти этот проект Angular в моем репозитории на GitHub. Спасибо за прочтение!