如何更新状态变更指令(How to update Directive on State Changes)

编程入门 行业动态 更新时间:2024-10-28 00:24:49
如何更新状态变更指令(How to update Directive on State Changes)

我有一个根状态,定义Angular模板的整体结构。 在根状态下,我有侧边栏包含动态菜单通过指令根据状态更改。 喜欢这个:

.state(‘root', { abstract: true, url: ‘/root', templateUrl: ‘views/root.html', })

root.html包含sidebar.html ,其中包含通过Directive调用的动态菜单,如下所示:

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观察器来触发重新编译指令,但它不会在第一次(或)之后再次重新编译它可能正在重新编译但是模板中没有看到更改(这是我现在的代码,我将给出下面)。 将侧边栏移动到单独的子状态而不是将其置于根状态工作,但它胜过目的,因为我试图首先在根状态中加载整体结构,并且仅在后续状态更改中刷新菜单部分。

我不确定如何处理这个问题。 我有一种感觉,我的方法可能不合时宜,并希望有人可以在这里指导我。 这是我目前的指令代码:

.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); } } }])

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 to scope 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); } } }])

最满意答案

您可以使用模板摆脱编译业务。 你的模板看起来像这样:

<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>

所以你的指令代码看起来应该是这样的

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 }); } }

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 }); } }

更多推荐

本文发布于:2023-07-22 01:03:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1215534.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:指令   状态   update   Directive   State

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!