Глобальные кнопки «Назад/Далее» в AngularJS
-
20-12-2019 - |
Вопрос
У меня есть несколько кнопок навигации в веб-приложении в стиле мастера Angular.Из косметических соображений их необходимо удалить из каждого партиала и добавить в корень index.html:
<!-- Global navigation buttons for all partials -->
<div class="navbar navbar-fixed-top">
<button class="btn btn-default" back-action>Back</button>
<button class="btn btn-default" next-action>Next</button>
</div>
<div class="container ng-view ng-cloak">
<!-- Partials rendered in here, managed by $routeProvider-->
</div>
Я попытался изолировать эту логику, используя директивы и переменные области, чтобы связать событие щелчка и применить целевые пункты назначения для каждого фрагмента:
.directive('nextAction', ['$location', function($location) {
return {
restrict: 'A',
link: function(scope, elm) {
elm.on('click', function () {
var nextUrl = scope.nextUrl;
$location.url(nextUrl);
});
}
};
}])
Затем URL-адреса определяются в каждом контроллере:
.controller('FirstStepCtrl', ['$scope', function ($scope) {
$scope.backUrl = '/';
$scope.nextUrl = '/first/second';
...
Проблема в том, что scope.nextUrl
является неопределенный поскольку область действия директивы не наследует область действия контроллера.
Помимо того, что в настоящее время он не работает, этот подход также кажется мне немного хрупким, поскольку он опирается на логику навигации, встроенную в код контроллера.
Как я могу создать более эффективные глобальные кнопки «Назад/Далее», которые будут динамически перенаправляться на основе текущей «страницы»?
Решение
Используйте диспетчер состояний для обработки обратного и следующего URL-адресов.Освободите контролеров от этой ответственности.Затем внедрите его в директивы, которые обрабатывают кнопки «Назад» и «Далее».
.factory('stateMgr', ['$rootScope', function ($rootScope) {
var stateMgr = {
backUrl: '',
nextUrl: ''
};
$rootScope.$on('$routeChangeSuccess', function (nextRoute, lastRoute) {
// logic in here will look at nextRoute and then set back and next urls
// based on new route
// e.g. stateMgr.backUrl = '/'; stateMgr.nextUrl = '/whatever';
});
return stateMgr;
}]);
затем
.controller('FirstStepCtrl', ['$scope', function ($scope) {
// do not need to do anything with back/next urls in here
...
и
.directive('nextAction', ['$location', 'stateMgr', function($location, stateMgr) {
return {
restrict: 'A',
link: function(scope, elm) {
elm.on('click', function () {
$location.url(stateMgr.nextUrl);
});
}
};
}])