如何更新状态更改指令 [英] How to update Directive on State Changes
问题描述
我有一个根状态,它定义了 Angular 模板的整体结构.在根状态中,我包含侧边栏,其中包含通过基于状态更改的指令的动态菜单.像这样:
.state('root', {摘要:真实,网址: ‘/root’,templateUrl: 'views/root.html',})
root.html
包含具有通过指令调用的动态菜单的 sidebar.html
,如下所示:
sidebar.html
该指令显示基于 $state.includes()
的菜单.但是发生的情况是,该指令在第一次加载时显示良好,但在状态更改期间不会更新该指令.为了解决这个问题,我尝试了以下方法但没有任何效果:
- 在主控制器中将
$state
添加到scope
但它仍然没有改变指令一旦它首先被编译. - 尝试添加
$stateChangeSuccess
观察器来触发重新编译指令,但它没有第一次后重新编译(或)也许它正在重新编译但模板中没有看到更改(这是我现在拥有的代码我将在下面给出). - 在单独的子项中移动侧边栏状态而不是让它处于根状态工作,但它击败了目的,因为我试图在根中加载整体结构状态第一,仅在后续状态刷新菜单部分变化.
我不太确定如何处理这个问题.我有一种感觉,我的方法可能不正常,希望有人能在这里指导我.这是我目前的指令代码:
.directive('sidebarMenus', ['$compile', '$state', '$rootScope',函数($compile,$state,$rootScope){返回 {限制:'A',替换:真的,链接:功能(范围,元素,属性){var state = scope.$state;//主控制器的作用域//HTML 模板函数构造Html(状态){var htmlText = '';//第一个子状态如果(state.includes('root.child1')){var htmlText = 'Child 1 Menu ';}//第二个子状态如果(state.includes('root.child2')){var htmlText = '<li>Child 2 Menu</li>';}//第三个子状态如果(state.includes('root.child3')){var htmlText = 'Child 3 Menu ';}$compile(htmlText)(scope, function( _element, _scope) {element.replaceWith(_element);});}$rootScope.$on('$stateChangeSuccess', function() {var state = scope.$state;//scope.$state 添加到主控制器中构造Html(状态);});//初始加载构造Html(状态);}}}])
使用模板可以摆脱编译业务.您的模板可能如下所示:
Child 1 Menu <li ng-if="state.includes('root.child2')">子2菜单</li><li ng-if="state.includes('root.child3')">子3菜单</li>
所以你的指令代码应该是这样的
return {限制:'A',替换:真的,模板:'<li ng-if="state.includes('root.child1')">子 1 菜单</li><li ng-if="state.includes('root.child2')">子2菜单</li><li ng-if="state.includes('root.child3')">子3菜单</li>'链接:功能(范围,元素,属性){$scope.state = scope.$state;//主控制器的作用域$rootScope.$on('$stateChangeSuccess', function() {$scope.state = scope.$state;//scope.$state 添加到主控制器中});}}
I have a root state that defines the overall structure of the Angular template. In the root state, I have the sidebar included that has dynamic menus via directive that changes based on the state. Like this:
.state(‘root', {
abstract: true,
url: ‘/root',
templateUrl: ‘views/root.html',
})
root.html
includes the sidebar.html
that has dynamic menu called through Directive like this:
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>
The directive shows the menu based on $state.includes()
. But what happens is, the directive shows fine in the first load but it doesn’t update the directive during state changes. To resolve this, I tried the following methods but nothing worked:
- Added the
$state
toscope
in Main controller but it still doesn’t change the directive once it is compiled first. - Tried adding
$stateChangeSuccess
watcher to trigger recompiling the directive, but it doesn’t recompile again after the first time (or) maybe it is recompiling but the changes are not seen in the template (this is the code I have now which I will give below). - Moving the sidebar inside separate child states instead of having it in root state works, but it beats the purpose since I am trying to load the overall structure in the root state first and only refresh the menu sections in subsequent state changes.
I am not really sure how to approach this. I have a feeling my approach can be out of whack and hoping someone can guide me here. This is my directive code at the moment:
.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);
}
}
}])
You can get rid of the compile business by using template. You template could look something like this:
<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>
So your directive code should look sth like this
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
});
}
}
这篇关于如何更新状态更改指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!