Angular $location.path не работает

У меня есть вопрос, похожий на этот, но другой.

Здесь я пытаюсь добавить прослушиватель событий для window.postMessage обработчик.

app.run(function ($location, $window, $rootScope) {
  $window.addEventListener('message', function(e) {
      $location.path("/abc");
      console.log($location.path()); // this prints "/abc" as expected

      $rootScope.$apply(); // this has no effect

      $scope = angular.element(document).scope(); // this is the same as $rootScope
      $scope.$apply(); // so this also has no effect
  });
});

$location.path не распознается Angular.

В другом вопросе говорится, что я должен называть $apply() в области видимости, но доступная мне только область $rootScope и вызов $apply() на этом не работает.

Комментарий к ответу предполагает, что область может быть получена с помощью

$scope = angular.element(document).scope()

но это дает мне $rootScope, который не работает.

Как мне получить angular, чтобы изменить изменения в $location.path()? Есть ли лучший способ зарегистрировать обратный вызов message таким образом, что я могу изменить путь?

Ответ 1

Вы должны запустить выражение как функцию в методе $apply(), например

app.run(function ($location, $window, $rootScope) {
  $window.addEventListener('message', function(e) {
      $rootScope.$apply(function() {
        $location.path("/abc");
        console.log($location.path());
      });
  });
});

См. documentation - ng. $rootScope.Scope.

Если вы хотите улучшить тестируемость, используйте $console вместо console и добавьте этот объект.

Ответ 2

Принятое решение не подходит для этого. В идеале вам не нужно вмешиваться в цикл дайджеста (что делает $apply()).

Лучший способ по мне - это вызов $location.path() из MainController. Используйте $emit - $on, чтобы отправить его в MainController и получить вызов функции $location.path. Он будет перенаправлять вас безупречно, не вмешиваясь в цикл дайджеста. Надеюсь, это поможет кому-то.

Ответ 3

Существует решение без $timeout.

Просто запретите перенаправление на состояние по умолчанию перед использованием $state.go

event.preventDefault();
$state.go('root');

Ответ 4

У меня была та же проблема, моя ошибка заключалась в том, что я плохо запускал директиву ng-click на моем элементе.

Плохой пример:

<a **href="#"** ng-click="myFunctionChangeLocationPath()">...

Пример хорошо:

<a ng-click="myFunctionChangeLocationPath()">...

И вы можете исправить эту проблему!