Как обновить директиву об изменениях состояния
У меня есть корневое состояние, которое определяет общую структуру углового шаблона. В корневом состоянии у меня есть боковая панель, включающая динамические меню с помощью директивы, которая изменяется в зависимости от состояния. Вот так:
.state(‘root', {
abstract: true,
url: ‘/root',
templateUrl: ‘views/root.html',
})
root.html
включает в себя sidebar.html
, который имеет динамическое меню, вызываемое через директиву следующим образом:
sidebar.html
<ul class="nav" id="side-menu">
<li class="nav-header">
<img alt="avatar" ng-src="{{ avatar }}" />
</li>
<!—Dynamic Menus Directive -->
<li sidebar-menus></li>
</ul>
Директива показывает меню, основанное на $state.includes()
. Но что происходит, директива показывает нормально в первой загрузке, но она не обновляет директива при изменении состояния. Чтобы решить эту проблему, я попробовал следующие методы, но ничего не вышло:
- добавил
$state
вscope
в Главном контроллере, но это по-прежнему не меняет директиву как только он будет скомпилирован первым. - пытался добавить
$stateChangeSuccess
watcher для запуска перекомпиляции директивы, но это не так перекомпилировать снова после первого раза (или) может быть, это перекомпиляция, но изменения не видны в шаблоне (это код, который у меня сейчас есть который я приведу ниже). - перемещение боковой панели внутрь отдельного дочернего элемента состояния вместо того, чтобы иметь его в корневом состоянии работает, но он бьет цель так как я пытаюсь загрузить общую структуру в корень состояние первое и только обновить разделы меню в последующем состоянии изменения.
Я не совсем уверен, как подойти к этому. Я чувствую, что мой подход может быть неуместным и надеюсь, что кто-то сможет направить меня сюда. Это мой директивный код на данный момент:
.directive('sidebarMenus', ['$compile', '$state', '$rootScope',
function($compile, $state, $rootScope) {
return {
restrict: 'A',
replace: true,
link: function(scope, element, attrs) {
var state = scope.$state; // Scope from Main Controller
// HTML Template
function contructHtml(state) {
var htmlText = '';
// First Child State
if (state.includes('root.child1')) {
var htmlText = '<li>Child 1 Menu</li>';
}
// Second Child State
if (state.includes('root.child2')) {
var htmlText = '<li>Child 2 Menu</li>';
}
// Third Child State
if (state.includes('root.child3')) {
var htmlText = '<li>Child 3 Menu</li>';
}
$compile(htmlText)(scope, function( _element, _scope) {
element.replaceWith(_element);
});
}
$rootScope.$on('$stateChangeSuccess', function() {
var state = scope.$state; // scope.$state is added in main controller
contructHtml(state);
});
// Initial Load
contructHtml(state);
}
}
}])
1 ответ:
Вы можете избавиться от компиляции с помощью шаблона. Ваш шаблон может выглядеть примерно так:
<li ng-if="state.includes('root.child1')">Child 1 Menu</li> <li ng-if="state.includes('root.child2')">Child 2 Menu</li> <li ng-if="state.includes('root.child3')">Child 3 Menu</li>
Таким образом, ваш код директивы должен выглядеть sth следующим образом
return { restrict: 'A', replace: true, template:'<div> <li ng-if="state.includes('root.child1')">Child 1 Menu</li> <li ng-if="state.includes('root.child2')">Child 2 Menu</li> <li ng-if="state.includes('root.child3')">Child 3 Menu</li> </div>' link: function(scope, element, attrs) { $scope.state = scope.$state; // Scope from Main Controller $rootScope.$on('$stateChangeSuccess', function() { $scope.state = scope.$state; // scope.$state is added in main controller }); } }