Angular:更改事件处理程序内的路径不起作用
Angular: Changing path inside event handler not working
我是 angular 的新手,在更改事件处理程序内部的位置时遇到问题。该处理程序用于位于 google 地图上的标记。我正在使用 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 语句。但是,位置没有改变。
这是因为我在 angular 的 "context" 之外,因为我通过 google 映射设置了事件侦听器吗?
附加信息
感谢关于使用 window.location 的建议。我之前没有提到的是地图是局部视图的一部分,所以我不想触发页面重新加载——我希望 angular 根据位置变化更新局部视图。我知道它可以做到,因为 $location.path('/unit') 在该事件处理程序之外工作得很好。
问题是 Google 地图事件回调 运行 在 Angular 上下文之外。调用 $location.path("...")
是完全正确的(您应该 NOT 在 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 上下文中触发;当您的函数 returns、Angular 触发 $digest 循环时,它会更新所有绑定。 $digest 循环将处理任何 $location 更改。
HOWEVER... google.maps.event.addListener
的回调在 Angular 上下文之外触发 later。 Angular 不会看到任何范围更改或您在该回调中所做的 $location
更改(至少,不会立即 - 直到下一次 $digest 循环发生在 运行,无论何时是)。
您需要将对 $scope.pinClicked(marker)
的调用包装在 $scope.$apply
内,如下所示:
google.maps.event.addListener(marker, 'click', function(tgt) {
$scope.$apply(function() {
$scope.pinClicked(marker);
});
});
通过将调用包装在 $scope.$apply
中,您实际上已经告诉 Angular、"Hey, run the code in this function, and then kick off a $digest cycle."
我是 angular 的新手,在更改事件处理程序内部的位置时遇到问题。该处理程序用于位于 google 地图上的标记。我正在使用 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 语句。但是,位置没有改变。
这是因为我在 angular 的 "context" 之外,因为我通过 google 映射设置了事件侦听器吗?
附加信息
感谢关于使用 window.location 的建议。我之前没有提到的是地图是局部视图的一部分,所以我不想触发页面重新加载——我希望 angular 根据位置变化更新局部视图。我知道它可以做到,因为 $location.path('/unit') 在该事件处理程序之外工作得很好。
问题是 Google 地图事件回调 运行 在 Angular 上下文之外。调用 $location.path("...")
是完全正确的(您应该 NOT 在 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 上下文中触发;当您的函数 returns、Angular 触发 $digest 循环时,它会更新所有绑定。 $digest 循环将处理任何 $location 更改。
HOWEVER... google.maps.event.addListener
的回调在 Angular 上下文之外触发 later。 Angular 不会看到任何范围更改或您在该回调中所做的 $location
更改(至少,不会立即 - 直到下一次 $digest 循环发生在 运行,无论何时是)。
您需要将对 $scope.pinClicked(marker)
的调用包装在 $scope.$apply
内,如下所示:
google.maps.event.addListener(marker, 'click', function(tgt) {
$scope.$apply(function() {
$scope.pinClicked(marker);
});
});
通过将调用包装在 $scope.$apply
中,您实际上已经告诉 Angular、"Hey, run the code in this function, and then kick off a $digest cycle."