谷歌地点 API - Angular 2 / Typescript / Ionic 2

4

有人将它转换为TypeScript了吗?

  var map;
  var infowindow;

  function initMap() {
    var pyrmont = {lat: -33.867, lng: 151.195};

    map = new google.maps.Map(document.getElementById('map'), {
      center: pyrmont,
      zoom: 15
    });

    infowindow = new google.maps.InfoWindow();
    var service = new google.maps.places.PlacesService(map);
    service.nearbySearch({
      location: pyrmont,
      radius: 500,
      type: ['store']
    }, callback);
  }

  function callback(results, status) {
    if (status === google.maps.places.PlacesServiceStatus.OK) {
      for (var i = 0; i < results.length; i++) {
        createMarker(results[i]);
      }
    }
  }

  function createMarker(place) {
    var placeLoc = place.geometry.location;
    var marker = new google.maps.Marker({
      map: map,
      position: place.geometry.location
    });

    google.maps.event.addListener(marker, 'click', function() {
      infowindow.setContent(place.name);
      infowindow.open(map, this);
    });
  }

我试图自己进行转换,如下所示,但控制台中出现错误,我将在代码下面展示,如果有人能告诉我我哪里出错了,那就太好了。

  constructor(public navCtrl: NavController, private navParams: NavParams, private ngZone: NgZone) {}

  ionViewDidLoad() {
    console.log('ionViewDidLoad DetailsPage');
    this.loadMap();
  }

  @ViewChild('map') mapElement: ElementRef;
  map: any;

  loadMap(){

    Geolocation.getCurrentPosition().then((position) => {

      let latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

      let mapOptions = {
        center: latLng,
        zoom: 15,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      }

      this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);

      let service = new google.maps.places.PlacesService(mapOptions);

      service.nearbySearch({
        location: latLng,
        radius: 500,
        type: ['pub']
      }, (results, status) => {
          this.callback(results, status)
      });

    }, (err) => {
      console.log(err);
    });

  }

  callback(results, status) {
    if (status === google.maps.places.PlacesServiceStatus.OK) {
      for (var i = 0; i < results.length; i++) {
        this.createMarker(results[i]);
      }
    }
  }

  createMarker(place){
    var placeLoc = place.geometry.location;
    var marker = new google.maps.Marker({
        map: this.map,
        position: place.geometry.location
    });

    let infowindow = new google.maps.InfoWindow();

    google.maps.event.addListener(marker, 'click', () => {
      this.ngZone.run(() => {
        infowindow.setContent(place.name);
        infowindow.open(this.map,this);
      });
    });
  }

  addMarker(){

    let marker = new google.maps.Marker({
      map: this.map,
      animation: google.maps.Animation.DROP,
      position: this.map.getCenter()
    });

    let content = "<h4>You are here!</h4>";          

    this.addInfoWindow(marker, content);

  }

  addInfoWindow(marker, content){

    let infoWindow = new google.maps.InfoWindow({
      content: content
    });

    google.maps.event.addListener(marker, 'click', () => {
      this.ngZone.run(() => {
        infoWindow.open(this.map, marker);
      });
    });
  }

控制台出现错误

Uncaught TypeError: this.b.getElementsByTagName is not a function
    at B5.attributionText_changed (places_impl.js:28)
    at zb (js?key=AIzaSyAZTATsl9JjVKodXRnzeSk52Ndvtz-HPPU&libraries=places:36)
    at B5._.y.bindTo (js?key=AIzaSyAZTATsl9JjVKodXRnzeSk52Ndvtz-HPPU&libraries=places:104)
    at Object.f6.f (places_impl.js:38)
    at Hw.<anonymous> (js?key=AIzaSyAZTATsl9JjVKodXRnzeSk52Ndvtz-HPPU&libraries=places:137)
    at js?key=AIzaSyAZTATsl9JjVKodXRnzeSk52Ndvtz-HPPU&libraries=places:105
    at Object.<anonymous> (js?key=AIzaSyAZTATsl9JjVKodXRnzeSk52Ndvtz-HPPU&libraries=places:37)
    at js?key=AIzaSyAZTATsl9JjVKodXRnzeSk52Ndvtz-HPPU&libraries=places:105
    at js?key=AIzaSyAZTATsl9JjVKodXRnzeSk52Ndvtz-HPPU&libraries=places:37
    at js?key=AIzaSyAZTATsl9JjVKodXRnzeSk52Ndvtz-HPPU&libraries=places:105

特别是在控制台文件中提到的内容。

b.getElementsByTagName("a"),c=0;c<_.w(b);c++)b[c].style.color="#444";this.H&&this.H.set("placesDataProviders",a)};B5.prototype.hide_changed=function(){_.kA(this.b,!this.get("hide"))};_.t(D5,_.y);_.k=D5.prototype;_.k.input_changed=function(){window.clearTimeout(this.f);this.f=window.setTimeout((0,_.p)(this.Ol,this),100)};_.k.Ol=function(){var a=this.l,b=this.Lb();a!=b&&(H5(this),this.l=b);this.f=null};_.k.Jm=function(){if(this.Tc())J5(this,this.Lb());else{var a={name:this.Lb()};this.Ef(a)}};

尝试使用 Geolocation.getCurrentPosition((position) => { 而不是 Geolocation.getCurrentPosition().then((position) => {。 - Yvan
3个回答

4

如果您添加了一个回调函数,this上下文将丢失。有多种方法可以解决此问题,其中一种是使用匿名函数包装器:

service.nearbySearch({
  location: latLng,
  radius: 500,
  type: ['pub']
}, (results, status) => {
  this.callback(results, status);
});

请注意,当您使用来自google.mapsaddListener调用时,不会触发变更检测周期。有关更多信息,请参见此答案。您可能会在addInfoWindow函数中遇到这个问题:

@Component({
    selector : 'maps-test',
    template : '<div #map></div>'
})
export class MapsTestComponent {

  @ViewChild('map')
  mapElement: ElementRef;

  constructor(private ngZone: NgZone){}

  ngAfterViewInit() {
      loadMap();
  }

  loadMap(){

    Geolocation.getCurrentPosition().then((position) => {

      let latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

      let mapOptions = {
        center: latLng,
        zoom: 15,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      }

      this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);

            let service = new google.maps.places.PlacesService(this.map);


      service.nearbySearch({
        location: latLng,
        radius: 500,
        type: ['pub']
      }, (results, status) => {
          this.callback(results, status)
      });

    }, (err) => {
      console.log(err);
    });

  }

  callback(results, status) {
    if (status === google.maps.places.PlacesServiceStatus.OK) {
      for (var i = 0; i < results.length; i++) {
        this.createMarker(results[i]);
      }
    }
  }

  createMarker(place){
    var placeLoc = place.geometry.location;
    var marker = new google.maps.Marker({
        map: this.map,
        position: place.geometry.location
    });

    let infowindow = new google.maps.InfoWindow();

    google.maps.event.addListener(marker, 'click', () => {
      this.ngZone.run(() => {
        infowindow.setContent(place.name);
        infowindow.open(this.map,this);
      });
    });
  }

  addMarker(){

    let marker = new google.maps.Marker({
      map: this.map,
      animation: google.maps.Animation.DROP,
      position: this.map.getCenter()
    });

    let content = "<h4>You are here!</h4>";          

    this.addInfoWindow(marker, content);

  }

  addInfoWindow(marker, content){

    let infoWindow = new google.maps.InfoWindow({
      content: content
    });

    google.maps.event.addListener(marker, 'click', () => {
      this.ngZone.run(() => {
        infoWindow.open(this.map, marker);
      });
    });
  }
}

嘿,感谢您的快速回复,我在更改后仍然遇到“找不到名称回调”的问题。 - BA1995
抱歉,我的错。我已经更新了我的答案。你应该在它前面加上 this,同时在你的初始问题中添加错误可能会有很大帮助:D - Poul Kruijt
我想说这是我的错!:D 这已经修复了错误 :) 尽管它在前端上没有工作,在控制台中我现在有Uncaught TypeError: this.b.getElementsByTagName is not a function 你有任何想法吗? - BA1995
老实说,我对这个有点困惑...你能给我演示一下吗?我还是个新手,所以这对我来说仍然是一个学习曲线!因为最初的问题已经解决了,所以我标记了答案为正确。 - BA1995
我放了未经测试的代码,但这就是我应该做的方式 ;) - Poul Kruijt
显示剩余6条评论

1
我想更新一下这个答案。我正在使用Ionic编写的应用程序,它是一个基于Angular的库。我能够使用这段代码并使其正常工作,但我不得不改变一件事情。信息窗口无法打开,并且一直抛出“Uncaught TypeError: this.b.getElementsByTagName不是函数”的错误。为了解决这个问题,我不得不改变

google.maps.event.addListener(marker, 'click', () => {
  this.ngZone.run(() => {
    infowindow.setContent(place.name);
    infowindow.open(this.map,this);
  });

google.maps.event.addListener(marker, 'click', () => {
      this.ngZone.run(() => {
        infowindow.setContent(place.name);
        infowindow.open(this.map,this.infowindow);
      });

添加

this.infowindow

这是关键。希望能帮助到遇到和我一样问题的人。


0

希望这可以帮到你。我最近的一个项目中将所有相关类型转换为TypeScript。

此外,正如您在我的应用程序后端中所看到的,一个自定义URL被附加到PlaceResult,因此我正在使用接口扩展类型以适应我的用例。

// docs: https://developers.google.com/maps/documentation/places/web-service/search-nearby#nearby-search-responses

export interface RRPlaceResult extends PlaceResult {
    url: string;
}

export type PlaceResult = {
    html_attributions: string[];
    results: Place[];
    status: PlacesSearchStatus;
    error_message?: string;
    info_messages?: string[];
    next_page_token?: string;
};

export type Place = {
    address_components?: AddressComponent[];
    adr_adress?: string;
    business_status?: string;
    curbside_pickup?: boolean;
    current_opening_hours?: PlaceOpeningHours;
    delivery?: boolean;
    dine_in?: boolean;
    editorial_summary?: PlaceEditorialSummary;
    formatted_address?: string;
    formatted_phone_number?: string;
    geometry?: Geometry;
    icon?: string;
    icon_background_color?: string;
    icon_mask_base_uri?: string;
    international_phone_number?: string;
    name?: string;
    opening_hours?: PlaceOpeningHours;
    permanently_closed?: boolean; // deprecated
    photos?: PlacePhoto[];
    place_id?: string;
    plus_code?: PlusCode;
    price_level?: number;
    rating?: number;
    reference?: string; // deprecated
    reservable?: boolean;
    reviews?: PlaceReview[];
    scope?: string; //deprecated
    secondary_opening_hours?: PlaceOpeningHours[];
    serves_beer?: boolean;
    serves_breakfast?: boolean;
    serves_brunch?: boolean;
    serves_dinner?: boolean;
    serves_lunch?: boolean;
    serves_vegetarian_food?: boolean;
    serves_wine?: boolean;
    takeout?: boolean;
    types?: string[];
    url?: string;
    user_ratings_total?: number;
    utc_offset?: number;
    vicinity?: string;
    website?: string;
    wheelchair_accessible_entrance?: boolean;
};

export type PlacesSearchStatus = 'OK' | 'ZERO_REULTS' |
    'INVALID_REQUEST' | 'OVER_QUERY_LIMIT' | 'REQUEST_DENIED' |
    'UNKNOWN_ERROR';

export type AddressComponent = {
    long_name: string;
    short_name: string;
    types: string[];
};

export type PlaceEditorialSummary = {
    language?: string;
    overview?: string;
};

export type Geometry = {
    location: LatLngLiteral;
    viewport: Bounds;
};

export type LatLngLiteral = {
    lat: number;
    lng: number;
};

export type Bounds = {
    northeast: LatLngLiteral;
    southwest: LatLngLiteral;
};

export type PlaceOpeningHours = {
    open_now?: boolean;
    periods?: PlaceOpeningHoursPeriod[];
    special_days?: PlaceSpecialDay[];
    type?: string;
    weekday_text?: string[];
};

export type PlaceOpeningHoursPeriod = {
    open: PlaceOpeningHoursPeriodDetail;
    close?: PlaceOpeningHoursPeriodDetail;
};

export type PlaceSpecialDay = {
    date?: string;
    exceptional_hours?: boolean;
};

export type PlaceOpeningHoursPeriodDetail = {
    day: number;
    time: string;
    date?: string;
    truncated?: boolean;
};

export type PlacePhoto = {
    height: number;
    html_attributions: string[];
    photo_reference: string;
    width: number;
};

export type PlusCode = {
    global_code: string;
    compound_code?: string;
};

export type PlaceReview = {
    author_name: string;
    rating: number;
    relative_time_description: string;
    time: number;
    author_url?: string;
    language?: string;
    original_language?: string;
    profile_photo_url?: string;
    text?: string;
    translated?: boolean;
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接