【问题标题】:Unable to set angular variable inside callback无法在回调中设置角度变量
【发布时间】:2018-10-21 17:44:12
【问题描述】:

我正在使用谷歌地图路线服务来计算行程时间。

this.mapsAPILoader.load().then(() => {
  const p1 = new google.maps.LatLng(50.926217, 5.342043);
  const p2 = new google.maps.LatLng(50.940525, 5.353626);

  const directionsService = new google.maps.DirectionsService();
  const request = {
    origin: p1,
    destination: p2,
    travelMode: google.maps.TravelMode.DRIVING,
    unitSystem: google.maps.UnitSystem.METRIC,
  };

  directionsService.route(request, (response, status) => {

    if (status === google.maps.DirectionsStatus.OK) {
      const point = response.routes[0].legs[0];
      // console.log(point.duration.text);
      this.travelTimeDriving = point.duration.text;
    }
  });


});

控制台记录了正确的驾驶时间,但我的变量 this.travelTimeDriving 保持为空。
我猜它与回调函数和范围有关,但我无法修复它。
路由函数也返回 void,没有承诺,所以我不能使用 .then()

【问题讨论】:

  • 你能解释一下你为什么投反对票吗?

标签: javascript angular google-maps typescript directions


【解决方案1】:

我认为你的范围不是你期望的那样是正确的。 根据您使用的编辑器/IDE,在引用时应该会给您一个错误

this.travelTimeDriving = point.duration.text;

如果您的范围不正确/变量未在您期望的范围内声明。在我看来,您应该引用类成员,您的类中是否声明了该变量(调用此函数)?

我假设如果您在设置后立即记录该值,您会看到结果。

 if (status === google.maps.DirectionsStatus.OK) {
  const point = response.routes[0].legs[0];
  // console.log(point.duration.text);
  this.travelTimeDriving = point.duration.text;
  console.log(this.travelTimeDriving);
}

您应该能够通过 console.log 或设置断点并检查该值来确定“this”此时的范围。

如果你能分享更多的周边代码会更容易帮助你更接近。

【讨论】:

  • 我在同一个类中声明了变量 travelTimeDriving: string;
  • 当我像你的例子一样登录时,它正在记录正确的值,奇怪
  • 当我记录“this”时,它会记录当前组件,因此应该是正确的
  • 当我在directionsService.route() 之外设置this.travelTimeDriving 时,它正在工作,但此时我还没有point.duration.text 值
  • 如果 route() 函数只返回一个很好的承诺
【解决方案2】:

使用 NgZone 确保回调将绑定到范围。工作样本:

import { Component, OnInit, NgZone } from '@angular/core';
declare const google: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  travelTimeDriving = '';

  constructor(private ngZone: NgZone) {}

  ngOnInit() {
    let mapProp = {
        center: new google.maps.LatLng(51.508742, -0.120850),
        zoom: 5,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    let map = new google.maps.Map(document.getElementById("googleMap"), mapProp);

    const p1 = new google.maps.LatLng(50.926217, 5.342043);
    const p2 = new google.maps.LatLng(50.940525, 5.353626);

    const directionsService = new google.maps.DirectionsService();
    const request = {
      origin: p1,
      destination: p2,
      travelMode: google.maps.TravelMode.DRIVING,
      unitSystem: google.maps.UnitSystem.METRIC,
    };

    directionsService.route(request, (response, status) => this.ngZone.run(() => {

      if (status === google.maps.DirectionsStatus.OK) {
        const point = response.routes[0].legs[0];
        this.travelTimeDriving = point.duration.text;
      }
    }));
  }
}

【讨论】:

  • 以及何时/如何将它分配给我的全局变量 this.travelTimeDriving 以便我可以在我的 html {{travelTimeDriving }} 中使用它?
  • 我正在运行一个沙箱来回复这个问题,但是现在,你有没有试过import 'rxjs/add/operator/toPromise';所以你可以打电话给directionsService.route(request, (response, status)).toPromise().then()
  • 这听起来像是一个很好的解决方案,但我收到了这个错误:“void”类型上不存在属性“toPromise”
  • 好了,我能够重现您的问题。解决方法如上。
  • 可能无法在回调中设置角度变量。此问题与谷歌地图和路线服务无关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多