Использование $location.path() из разных контроллеров для отображения кнопок навигации: AngularJS
Это расширение двух предыдущих вопросов; Как использовать угловое ng-hide на основе страницы / маршрута, на котором я сейчас нахожусь? и как я могу использовать ng-hide, если $location.url == base (root) url? Оба касаются отображения элементов навигации, используя $location.path()
в зависимости от текущего маршрута.
У меня очень простой SPA в стиле списка контактов с только верхним и нижним колонтитулами и различными видами. Заголовок имеет 3 кнопки навигации. Каждый использует функцию, связанную с ng-click
изменить путь и логический тест для отображения, например
<button ng-click="changePath('/summary')" ng-hide="path == '/summary' ">Summary</button>
Внутри прикрепленного контроллера заголовка, с $location
Сервис введен у нас.
var vm = this;
vm.path = $location.path();
vm.changePath = changePath;
function changePath (newPath) {
this.path = newPath;
$location.path(newPath);
}
Это все работает, как и ожидалось, за исключением двух случаев.
Во-первых, когда приложение впервые загружено. Конфигурация маршрута по умолчанию установлена на .otherwise({redirectTo : "/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
следует транслировать изменение маршрута /questions/43695200/angularjs-pejdzhing-s-locationpath-no-bez-perezagruzki-ngview/43695208#43695208. Обновление страницы, однако, предполагает, что, возможно, $digest
цикл должен быть вызван вызовом $apply
но это только кажется неправильным.
Я пробовал оборачивать $location.path()
внутри $timeout
согласно этому ответу /questions/26221503/locationpath-obnovlyaetsya-posle-vtorogo-klika/26221511#26221511 но это не сработало.
Отредактировано 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
это путь Я попробовал, но безуспешно.
Возможно, я пойду об этом совершенно неправильно. Любой совет будет с благодарностью.
Спасибо.
1 ответ
Ответ здесь: /questions/19728578/pochemu-myi-ispolzuem-translyatsiyu-rootscope-v-angularjs/19728582#19728582.
Очень просто: использовать пользовательский сервис для обработки всех изменений пути.
- Сервис Angular $location может быть внедрен в этот сервис.
- Внедрите эту услугу в каждый контроллер, где путь изменяется.
- Новый сервис использует $rootScope для трансляции изменений.
$rootScope.$broadcast("pathChanged", newPath);
Контроллер для кнопок навигации прослушивает трансляцию и обновляет свою модель для текущего пути соответственно. Это запускает представление (то есть кнопки навигации), которое будет отображаться или скрываться по мере необходимости.
$scope.$on("pathChanged", updatePath) function updatePath(evt, updatedPath) { vm.currentPath = updatedPath; }
Обновленный Plunk находится здесь: http://plnkr.co/edit/7bQn6G9HveHajBMdrDfR