1

私は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 ステートメントが実行されます。ただし、場所は変わりません。

これは、Googleマップを介してイベントリスナーを設定したため、角度の「コンテキスト」の外にいるためですか?

追加情報

window.location の使用に関する提案に感謝します。前に言及しなかったのは、マップが部分ビューの一部であるため、ページのリロードをトリガーしたくないということです。場所の変更に基づいて角度を付けて部分ビューを更新したいのです。$location.path('/unit') はそのイベント ハンドラーの外部で問題なく動作するため、これができることはわかっています。

4

1 に答える 1

2

問題は、Google マップのイベント コールバックが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 サイクルをトリガーし、すべてのバインディングを更新します。$location の変更を処理するのは $digest サイクルです。

ただし... 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 に答える