web-dev-qa-db-ja.com

Googleプレイスオートコンプリート+ Angular2

単純なGooglePlaces Autocomplete Angular2ディレクティブを作成していますが、問題は予測を取得できないことです(応答は常に空ですか?!)...

概念実証として、参照として可能な限り単純なコードスニペットを作成しました。

<!DOCTYPE html>
<html>

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

<body>
    <button type="button" onclick="go()">go</button>
    <input id="autocomplete" type="text"></input>
    <script>
    var autocomplete = null;

    function go() {
        autocomplete = new google.maps.places.Autocomplete(
            (document.getElementById('autocomplete')), {
                types: ['geocode']
            });
    }
    </script>
</body>

</html>

上記のコードは機能します-[移動]ボタンをクリックすると予測を取得できます。

さて、Angular2シナリオ:

私の_Layout.cshtmlファイルのheadセクションに次のタグがあります。

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

私の指示:

 import {Directive、ElementRef、Input} from '@ angular/core'; 
 
 declare var google:any; 
 
 @ Directive( {セレクター: '[googleplaces]'})
エクスポートクラスGooglePlacesDirective {
 
オートコンプリート:任意; 
 
コンストラクター(プライベートel:ElementRef) {
 
} 
 
 ngAfterContentInit(){
 this.autocomplete = new google.maps.places.Autocomplete(
( this.el.nativeElement)、
 {types:['geocode'、 'cities']}); 
} 
} 

そして単純なAngularコンポーネント:

<form [formGroup]="companyForm">

    .
    .
    .

    <div class="form-group">
        <label for="Location">Location</label>
        <input type="text" 
               class="form-control" 
               id="Location" 
               fromControlName="Location" 
               googleplaces>
    </div>
</form>

シナリオ2(角度)は機能しません。事実:

  • オートコンプリートが初期化されます(予想されるすべてのプロパティ/メソッドがあり、プレースホルダーは「場所を入力してください」などです...)
  • オートコンプリートは、入力された検索文字列の予測を返しません( "/ ** /xdc._ le3zv3 &&xdc._ le3zv3([4]) ")

また、Google API Consoleは、すべてが正常であると言っていますか?!スクリーンショットは次のとおりです。

ここに画像の説明を入力してください

ここで何が問題になる可能性がありますか?ありがとう...

8
stedejan
import {Directive, ElementRef, EventEmitter, Output} from '@angular/core';
import {NgModel} from '@angular/forms';

declare var google:any;

@Directive({
  selector: '[Googleplace]',
  providers: [NgModel],
  Host: {
    '(input)' : 'onInputChange()'
  }
})
export class GoogleplaceDirective {

   @Output() setAddress: EventEmitter<any> = new EventEmitter();
  modelValue:any;
  autocomplete:any;
  private _el:HTMLElement;


  constructor(el: ElementRef,private model:NgModel) {
    this._el = el.nativeElement;
    this.modelValue = this.model;
    var input = this._el;

    this.autocomplete = new google.maps.places.Autocomplete(input, {});
    google.maps.event.addListener(this.autocomplete, 'place_changed', ()=> {
      var place = this.autocomplete.getPlace();
      this.invokeEvent(place);

    });
  }

  invokeEvent(place:Object) {
    this.setAddress.emit(place);
  }

  onInputChange() {
    console.log(this.model);
  }
}

使用するには

<input type="text" class="form-control" placeholder="Location" name="Location" [(ngModel)]="address" #LocationCtrl="ngModel"
        Googleplace (setAddress)="getAddressOnChange($event,LocationCtrl)">
12
Habeeb

@Habeebの答えは素晴らしいスタートですが、これはよりクリーンな実装です。最初にグーグルマップのタイピングをインストールしますnpm install --save-dev @types/googlemapsそしてアプリのどこかにインポートしますimport {} from '@types/googlemaps'

import { Directive, ElementRef, EventEmitter, OnInit, Output } from '@angular/core';

@Directive({
  // xx is your app's prefix
  selector: '[xxPlaceLookup]'
})
export class PlaceLookupDirective implements OnInit {
  @Output() onSelect: EventEmitter<any> = new EventEmitter();

  private element: HTMLInputElement;

  constructor(el: ElementRef) {
    this.element = el.nativeElement;
  }

  ngOnInit() {
    const autocomplete = new google.maps.places.Autocomplete(this.element, {
      types: ['establishment'],
      componentRestrictions: {country: 'us'}
    });
    google.maps.event.addListener(autocomplete, 'place_changed', () => {
      const place = autocomplete.getPlace();
      this.onSelect.emit(place);
    });
  }
}
8
alalonde