【问题标题】:How to update Directive on State Changes如何更新关于状态变化的指令
【发布时间】:2016-02-21 18:55:39
【问题描述】:

我有一个根状态,它定义了 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);
        }
    }
}])

【问题讨论】:

  • 为什么要编译htmlText?里面没有指令。
  • 嗨@georgeawg 请问在这种情况下什么是理想的?
  • @Neel 使用模板而不是编译html,或者使用templateUrl。
  • 其实我发现问题中的解决方案非常有用!

标签: angularjs angularjs-scope angularjs-controller angular-directive


【解决方案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>

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

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

【讨论】:

  • 啊哈。所以基本上是compile 导致指令只编译一次而不是在状态更改期间更新?谢谢马亨德拉·辛格。我会试试你的建议。
  • 应该是scope.state = scope.$state。而不是var state = scope.$state.
猜你喜欢
  • 2011-03-07
  • 1970-01-01
  • 2020-09-23
  • 2019-08-06
  • 2020-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多