如何更新状态变化指令

How to update Directive on State Changes

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

.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()的菜单。但实际情况是,指令在第一次加载时显示正常,但在状态更改期间不会更新指令。为了解决这个问题,我尝试了以下方法但没有任何效果:

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

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

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