У меня есть контроллер для меню и контроллера для каждого вида. То, что я хочу достичь, - это добавить active
класс в пункт меню, чтобы визуально выбрать активный элемент меню. Чтобы получить эту работу, я создал службу для хранения текущего пункта меню (номер). Вот мой взгляд.
body
div.menu(ng-controller="menuCtrl")
ul
li(ng-class="{selected: menuItem===0}")
a(href='#/')
i.material-icons.medium visibility
li(ng-class="{selected: menuItem===1}")
a(href='#/posts')
i.material-icons.medium library_books
li(ng-class="{selected: menuItem===2}")
a(href='#/categories')
i.material-icons.medium loyalty
span test {{menuItem}} // test menuItem variable
div.row-fluid
ng-view
Здесь контроллер menuCtrl
app.controller('menuCtrl', ['$scope', '$http', 'global', '$interval', function($scope, $http, GLOBAL, $interval ) {
$scope.menuItem = GLOBAL.menuItem;
}])
Как вы можете видеть, я привязываю переменную от службы к локальной переменной переменной $scope
.
И вот моя служба
app.factory( 'global', function( $http ) {
return {
menuItem: 0,
}
})
Затем в каждом контроллере представления я добавляю строку для определения определенного значения для сервиса menuItem
следующим образом:
app.controller('postsCtrl', ['$scope', '$http', 'global', '$location', function($scope, $http, GLOBAL, $location ) {
// ...
GLOBAL.menuItem = 1;
// ...
}])
То же самое для всех других контроллеров представления, так что пункт menuItem
- 2,3,4 и т.д.
Проблема в том, что даже если кажется, что переменная menuItem
изменяется, если я нажимаю на несколько пунктов меню, значение в меню (где я помещаю тестовый комментарий) остается 0, и в результате только первый пункт меню имеет active
класс.
Зачем?
Вы должны использовать директивы, а не контроллеры для управления такими вещами.
Здесь скрипка, где "выбранная" директива облегчает жизнь, привязавшись к вашей государственной службе без какого-либо контроллера посередине.
<ul>
<li is-selected="1">Menu 1</li>
<li is-selected="2">Menu 2</li>
<li is-selected="3">Menu 3</li>
<li is-selected="4">Menu 4</li>
</ul>
В директиве мы не только отражаем выбранное состояние, но и управляем изменениями выбранного элемента с помощью $ watch и впрыскивания обработчика события click:
myApp.directive('isSelected', ['myService', function(myService) {
return {
scope: {},
link: function(scope, el, attrs) {
var id = parseInt(attrs.isSelected, 10),
unwatch = scope.$watch(
function() {
return myService.menu.selected;
},
function(val) {
if (val == id)
el.addClass("menuItemSelected")
else
el.removeClass("menuItemSelected")
}),
dst = scope.$on("$destroy", function() {
angular.element(el).off("click");
unwatch();
dst();
});
angular.element(el).on("click",function() {
scope.$apply(function() {myService.menu.selected = id;});
});
}
}
}]);