如何更新状态更改指令 [英] How to update Directive on State Changes

查看:30
本文介绍了如何更新状态更改指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个根状态,它定义了 Angular 模板的整体结构.在根状态中,我包含侧边栏,其中包含通过基于状态更改的指令的动态菜单.像这样:

.state('root', {摘要:真实,网址: ‘/root’,templateUrl: 'views/root.html',})

root.html 包含具有通过指令调用的动态菜单的 sidebar.html,如下所示:

sidebar.html

 

该指令显示基于 $state.includes() 的菜单.但是发生的情况是,该指令在第一次加载时显示良好,但在状态更改期间不会更新该指令.为了解决这个问题,我尝试了以下方法但没有任何效果:

  1. 在主控制器中将 $state 添加到 scope 但它仍然没有改变指令一旦它首先被编译.
  2. 尝试添加 $stateChangeSuccess 观察器来触发重新编译指令,但它没有第一次后重新编译(或)也许它正在重新编译但模板中没有看到更改(这是我现在拥有的代码我将在下面给出).
  3. 在单独的子项中移动侧边栏状态而不是让它处于根状态工作,但它击败了目的,因为我试图在根中加载整体结构状态第一,仅在后续状态刷新菜单部分变化.

我不太确定如何处理这个问题.我有一种感觉,我的方法可能不正常,希望有人能在这里指导我.这是我目前的指令代码:

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

    1. Added the $state to scope in Main controller but it still doesn’t change the directive once it is compiled first.
    2. 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).
    3. 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屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆