【问题标题】:Angularjs nested directive scope ambiguityAngularjs嵌套指令范围模糊
【发布时间】:2016-09-25 07:17:01
【问题描述】:

我正在创建一个选项卡指令,它允许用户添加选项卡。
一切正常,但 tab-entry 指令未读取 节点元素中的范围选定值,用于设置 活跃的班级。

即使我在 tabs 指令链接 >> > 函数中将选择的范围更改为 true,它也不会反映更改并且未设置活动类。

指令

 _app_dashboard.directive('tabs' , function(){
            return {    
                    restrict  : 'EA',

                    controller : function($scope){

                        $scope.tabEntries = this.tabEntries  = [];

                        $scope.select = function($event , item){

                                    //unselect All                                          
                                    this.tabEntries.forEach(function(tabentry , index){
                                    tabentry.selected = false;
                                    if(tabentry.heading == item){
                                        tabentry.selected = true;
                                    }
                                })                              
                            }
                    },

                    template : '<div class = "tab-container"><ul><li ng-repeat = "tabentry in tabEntries"><a href=""  ng-click="select($event , tabentry.heading)">{{tabentry.heading}}</a></li></ul><div ng-transclude></div></div>',  

                    transclude : true,
                    replace : false 
                }
        });
        _app_dashboard.directive('tabEntry' , function(){
            return {    
                        restrict : "EA",
                        require : "^tabs",
                        scope : {
                            heading : "@",
                        },

                        template : '<div ng-transclude></div>',
                        transclude : true,

                        link : function(scope , ele , attr , ctrl , transcludeFn){
                            scope.tabCtrlScope = ctrl;
                            scope.selected = true;

                            scope.tabCtrlScope.tabEntries.push(scope);


                        }
                }
        });

HTML

<tabs >
    <tab-entry  heading = 'Tab1'  ng-class = "{'active' : selected}">
        <div>The is the content of tab 1</div>
    </tab-entry>
    <tab-entry  heading = 'Tab2'  ng-class = "{'active' : selected}">
        <div>This is the content of tab 2</div>
    </tab-entry>

</tabs>

CSS

tab-entry {
    display : none;
}
tab-entry.active {
    display : block;
}

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-scope angularjs-ng-transclude


    【解决方案1】:

    您可以在内部设置选定的属性,这样您就不必在主模板中公开它:

    _app_dashboard.directive('tabEntry' , function(){
      return {    
        restrict : "EA",
        require : "^tabs",
        scope : {
          heading : "@"
        },
        template : '<div ng-class="{ active: selected }" ng-transclude></div>',
        transclude : true,
        link : function(scope , ele , attr , ctrl , transcludeFn){
          scope.tabCtrlScope = ctrl;
          scope.selected = true;
          scope.tabCtrlScope.tabEntries.push(scope);
        }
      }
    });
    

    CSS:

    tab-entry > div {
      display : none;
    }
    tab-entry > .active {
      display : block;
    }
    

    Check out this working plunker

    【讨论】:

    • 非常感谢!我现在可以理解范围是在自定义指令的模板内处理的。 +1
    【解决方案2】:

    您需要在指令声明的范围声明上设置属性 selected: '=' 以实现双向绑定。

    var _app_dashboard = angular.module('app', []);
    
    _app_dashboard.directive('tabs' , function(){
                return {    
                        restrict  : 'EA',
    
                        controller : function($scope){
    
                            $scope.tabEntries = this.tabEntries  = [];
    
                            $scope.select = function($event , item){
    
                                        //unselect All                                          
                                        this.tabEntries.forEach(function(tabentry , index){
                                        tabentry.selected = false;
                                        if(tabentry.heading == item){
                                            tabentry.selected = true;
                                        }
                                    })                              
                                }
                        },
    
                        template : '<div class = "tab-container"><ul><li ng-repeat = "tabentry in tabEntries"><a href=""  ng-click="select($event , tabentry.heading)">{{tabentry.heading}}</a></li></ul><div ng-transclude></div></div>',  
    
                        transclude : true,
                        replace : false 
                    }
            });
            _app_dashboard.directive('tabEntry' , function(){
                return {    
                            restrict : "EA",
                            require : "^tabs",
                            scope : {
                                heading : "@",
                                selected: '='
                            },
    
                            template : '<div ng-transclude></div>',
                            transclude : true,
    
                            link : function(scope , ele , attr , ctrl , transcludeFn){
                                scope.tabCtrlScope = ctrl;
                                scope.selected = true;
    
                                scope.tabCtrlScope.tabEntries.push(scope);
    
    
                            }
                    }
            });
    tab-entry {
        display : none;
    }
    tab-entry.active {
        display : block;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <div ng-app="app">
    <tabs >
        <tab-entry  heading = 'Tab1' selected="selected1"  ng-class = "{'active' : selected1}">
            <div>The is the content of tab 1</div>
        </tab-entry>
        <tab-entry  heading = 'Tab2' selected="selected2"   ng-class = "{'active' : selected2}">
            <div>This is the content of tab 2</div>
        </tab-entry>
    
    </tabs>
    </div>

    【讨论】:

    • 谢谢。这是解决这个问题的另一种方法。我可以得出结论,在自定义指令中,我们可以通过双向绑定获取属性,并在同一自定义指令的其他属性中使用相同的变量,而不是简单地将创建的新范围对象放在链接函数中。 +1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    • 2015-02-04
    • 1970-01-01
    • 1970-01-01
    • 2014-09-06
    相关资源
    最近更新 更多