1

我是 angular 新手,在更改事件处理程序内部的位置时遇到问题。该处理程序用于定位在谷歌地图上的标记。我正在使用 ng-map(非常棒)。

下面是创建标记的代码(在 $http get 的成功回调中运行):

for( i = 0; i < data.Pins.length; i++ )
{
    var marker = new google.maps.Marker({
        title: data.Pins[i].StreetAddress,
        position: new google.maps.LatLng(data.Pins[i].Latitude,data.Pins[i].Longitude),
        data: data.Pins[i],
        index: i,
    });

    google.maps.event.addListener(marker, 'click', function(tgt) {
        $scope.pinClicked(marker);
    });

    marker.setMap($scope.map);

    $scope.markers.push(marker);
}

事件处理程序非常简单:

$scope.pinClicked = function(marker) {
    if( marker.data.Homes.length == 1) $location.path("/home");
    else $location.path("/unit");
};

当我单击标记时,处理程序将执行,并执行 if/then/else 语句。但是,位置不会改变。

这是因为我在角度的“上下文”之外,因为我通过谷歌地图设置了事件监听器?

附加信息

感谢有关使用 window.location 的建议。我之前没有提到的是地图是局部视图的一部分,所以我不想触发页面重新加载——我希望 Angular 根据位置变化来更新局部视图。我知道它可以做到,因为 $location.path('/unit') 在该事件处理程序之外工作得很好。

4

1 回答 1

2

问题是 Google Maps 事件回调在 Angular 上下文之外运行。调用$location.path("...")是完全正确的(你不应该Angular 应用程序中使用window.location),但你必须在 Angular 控制的回调中使用定位服务。这不是在这里发生的。考虑一下您的代码摘录:

$http.get(..., function() {
  for (i = 0; i < data.Pins.length; i++) { // This is your FOR loop 
    ...
    google.maps.event.addListener(marker, 'click', function(tgt) {
      $scope.pinClicked(marker);
    });

回调(你的$http.get()函数)在 Angular 上下文中触发;当你的函数返回时,Angular 会触发一个 $digest 循环,它会更新所有绑定。$digest 循环将处理任何 $location 更改。

但是...回调在 Angular 上下文之外google.maps.event.addListener触发。Angular 不会看到任何范围更改或您在该回调中所做的更改(至少,不会立即 - 直到下一次 $digest 循环碰巧运行,无论何时)。$location

您需要将您的呼叫包装到$scope.pinClicked(marker)within $scope.$apply,如下所示:

google.maps.event.addListener(marker, 'click', function(tgt) {
  $scope.$apply(function() {
    $scope.pinClicked(marker);
  });
});

通过将调用包装在 中$scope.$apply,您实际上是在告诉 Angular,“嘿,运行这个函数中的代码,然后开始一个 $digest 循环。”

于 2015-04-26T23:48:32.273 回答