Использование $location.path() из разных контроллеров для отображения кнопок навигации: AngularJS

Это расширение 2 предыдущих вопросов; Как использовать angular ng-hide на основе страницы/маршрута, на котором я сейчас нахожусь? и Как я могу использовать ng-hide, если $location.url == базовый (корневой) URL? Оба касаются отображения элементов навигации с использованием $location.path(), зависит от текущего маршрута.

У меня есть очень простой SPA в стиле списка контактов, содержащий только верхний и нижний колонтитулы и различные представления. В шапке есть 3 кнопки навигации. Каждый использует функцию, привязанную к ng-click, чтобы изменить путь и логический тест для отображения, например.

<button ng-click="changePath('/summary')" ng-hide="path == '/summary' ">Summary</button>

Внутри прикрепленного HeaderController с внедренной службой $location у нас есть.

var vm = this;
vm.path = $location.path();
vm.changePath = changePath;

function changePath (newPath) {
    this.path = newPath;
    $location.path(newPath);
}

Все это работает, как и ожидалось, за исключением двух случаев.

Во-первых, при первой загрузке приложения. Конфигурация маршрута по умолчанию имеет значение .otherwise({redirectTo : "/summary"}, но кнопка сводка по-прежнему отображается.

Во-вторых, когда маршрут изменяется внутри просмотра страницы с другим контроллером. Например, на странице summary у каждого контакта есть ссылка, которая загрузит новую страницу со всеми подробностями.

<div ng-repeat="data in contacts">
    ...
    <span ng-click="showDetails(contacts.indexOf(data))">Info</span>
</div>

а связанный SummaryController снова просто использует $location для изменения маршрута

var vm = this;
vm.contacts = dataStore.getDetails();
vm.showDetails = showDetails;

function showDetails(index) {
    $location.path("/details/" + index);
}

Как и прежде, это работает так, как ожидалось; отображается представление с соответствующими сведениями, но кнопки навигации не обновляются.

В обоих случаях простое обновление страницы браузера отображает правильные кнопки навигации.

Насколько я понимаю, $location должен транслировать изменение маршрута https://stackoverflow.com/a/12429133/2980217. Обновление страницы, однако, предполагает, что, возможно, цикл $digest должен запускаться вызовом $apply, но это кажется неправильным.

Я пытался обернуть $location.path() внутри $timeout в соответствии с этим ответом https://stackoverflow.com/a/24144088/2980217, но это не сработало.


Отредактировано 2 декабря. Я создал скелетную версию приложения в виде планка http://plnkr.co/edit/7bQn6G9HveHajBMdrDfR.

Что касается проблемы с загрузкой приложения, кажется, что шаблон загружается первым, после чего $location.path() является пустой строкой. Чтобы преодолеть это, я использовал простое условие, чтобы вручную установить переменную currentPath.

Кажется, мне нужно обновить страницу. Согласно этой статье https://www.sitepoint.com/premium/books/angularjs-novice-to-ninja/preview/exploring-the-location-service-2f17ca5 использование $window.location.href — это правильный путь. Я попробовал это, но безуспешно.

Возможно, я иду об этом совершенно неправильно. Любые советы будут с благодарностью оценены.

Спасибо.


person magwitch    schedule 01.12.2015    source источник


Ответы (1)


Ответ здесь: https://stackoverflow.com/a/24831979/2980217.

Очень просто: используйте специальный сервис для обработки всех изменений пути.

  • В эту службу можно внедрить службу Angular $location.
  • Внедрите эту службу в каждый контроллер, где изменяется путь.
  • Новая служба использует $rootScope для трансляции изменений. $rootScope.$broadcast("pathChanged", newPath);
  • Контроллер кнопок навигации прослушивает трансляцию и соответствующим образом обновляет свою модель для текущего пути. Это вызывает отображение или скрытие вида (то есть кнопок навигации) по мере необходимости.

    $scope.$on("pathChanged", updatePath)
    
    function updatePath(evt, updatedPath) {
       vm.currentPath = updatedPath;
    }
    

Обновленный планк находится здесь: http://plnkr.co/edit/7bQn6G9HveHajBMdrDfR

person magwitch    schedule 03.12.2015