В данной статье я покажу вам как можно создать поиск на карте Google Maps в фреймворке Angular, с подсказками (автозаполнения).
Официальная документация полезная но в фреймворке Angular существует модуль Angular Google Maps (agm) который ещё больше облегчает работу с API карт.
Начало работы
Первое что нам нужно сделать это установить 2 пакета, используя Node Package Manager (npm):
- Angular Google Maps модуль
- Объявленные типы данных Google Maps в TypeScript
npm install @agm/core --save npm install @types/googlemaps --save-dev
Дальше, должны поменять декоратор @NgModule:
import { AgmCoreModule } from '@agm/core';
@NgModule({
imports: [
AgmCoreModule.forRoot({
apiKey: "вставьте тут ваш API_KEY от Google приложения",
libraries: ["places"]
}),
BrowserModule,
FormsModule,
ReactiveFormsModule
],
declarations: [ App ],
bootstrap: [ App ]
})
export class AppModule() {} Что делает выше описанный код?
- Подключаем AgmCoreModule из пакета @agm/core module.
- В свойстве imports используем метод AgmCoreModule.forRoot() чтобы указать рабочую зону модуля.
- Так-же заметите что мы используем модуль ReactiveFormsModule для работы с формами в Angular.
Создаём шаблон
Для примера добавлю стили и html код в @Component, но для реального проекта рекомендую выделить в отдельный файл стили и html.
@Component({
selector: 'my-app',
styles: [`
agm-map {
height: 300px;
}
`],
template: `
<div class="container">
<h1>Поиск с автозаполнением в Google Maps через Angular</h1>
<div class="form-group">
<input placeholder="search for location" autocorrect="off" autocapitalize="off" spellcheck="off" type="text" class="form-control" #search [formControl]="searchControl">
</div>
<agm-map [latitude]="latitude" [longitude]="longitude" [scrollwheel]="false" [zoom]="zoom">
<agm-marker [latitude]="latitude" [longitude]="longitude"></agm-marker>
</agm-map>
</div>
`
})
export class App implements OnInit {} Объяснения:
- Не забудьте задать высоту для карты. В данном случае я задал 300px.
- Для данного примера я использовал Bootstrap CSS стили, чтобы шаблон выглядел адекватно.
- Переменную связанную с input назвал search. Она объявлена в шаблоне при помощи символа решетка (#).
- Мой input имеет одностороннюю привязку данных с FormControl к общедоступной (в контроллере) переменной searchControl.
- Дальше я использую компонент agm-map передавая ему широту, долготу и zoom свойствами из моего контроллера, scrollwheel значением false.
- Добавил маркер на карту agm-marker передавая ему позицию на карте.
Реализуем Controller
Дальше мы должны создать controller. Он выглядит примерно так:
import { ElementRef, NgZone, OnInit, ViewChild } from '@angular/core';
import { FormControl } from '@angular/forms';
import { } from 'googlemaps';
import { MapsAPILoader } from '@agm/core';
export class App implements OnInit {
public latitude: number;
public longitude: number;
public searchControl: FormControl;
public zoom: number;
@ViewChild("search")
public searchElementRef: ElementRef;
constructor(
private mapsAPILoader: MapsAPILoader,
private ngZone: NgZone
) {}
ngOnInit() {
// установим широту и долготу и zoom по умолчанию
this.zoom = 4;
this.latitude = 47.017950;
this.longitude = 28.812735;
// создаём новый search FormControl
this.searchControl = new FormControl();
// устанавливаем на карту текущее местоположение посетителя
this.setCurrentPosition();
// загружаем места для автодополнения
this.mapsAPILoader.load().then(() => {
const autocomplete = new google.maps.places.Autocomplete(this.searchElementRef.nativeElement, {
types: ["address"]
});
autocomplete.addListener("place_changed", () => {
this.ngZone.run(() => {
// получаем результаты с местом
const place: google.maps.places.PlaceResult = autocomplete.getPlace();
// проверяем результат
if (place.geometry === undefined || place.geometry === null) {
return;
}
// установим широту, долготу и zoom
this.latitude = place.geometry.location.lat();
this.longitude = place.geometry.location.lng();
this.zoom = 12;
});
});
});
}
private setCurrentPosition() {
if ("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition((position) => {
this.latitude = position.coords.latitude;
this.longitude = position.coords.longitude;
this.zoom = 12;
});
}
}
} Рекомендую
Если хотите изучить быстро Angular и чтоб объяснили простым языком сложные вещи, то рекомендую платный курс по Angular от WebForMySelf. А если ещё не знакомы с данным издательством, можете пройти бесплатный курс по Angular.
Demo
Оригинал на английском можно почитать тут.