How to pass a variable through scope into directiv

2019-07-23 15:49发布

问题:

Inside an element directive named tabset, i am using element directive named tab twice which requires tabset.
I am doing a console.log(attr.newvar) from link of tabset.
newvar is the value passed into the scope of the tabset directive.

So the tabset gets called 2 times (which i suppose is correct), and hence output is consoled twice.

1st time, the console output is giving the correct output, but the 2nd time it is showing newvar as undefined .

but i am not able to access newvar through scope.newvar.In case of console.log(scope.newvar), i get output as undefined twice.

Why is this happening ?

HTML snippet

<tabset newvar="black">
    <tab></tab>
    <tab></tab>
</tabset>

JS snippet

.directive('tab',function(){
return{
    restrict:'E',
    require:'^tabset',
    transclude:true,
    scope:{
        heading:"@"
    },
    template:'<div ng-show="active" ng-transclude></div>',
    link:function(scope,elem,attr,tabsetCtrl){
        scope.active = false;
        tabsetCtrl.add(scope);
    }
}
})
.directive('tabset',function(){
return{
    restrict:'E',
    scope:{
        item:"=",
        newvar:"@"          
    },
    transclude:true,
    templateUrl:'/partials/tabset/tabset.html',
    bindToController:true,
    controllerAs:'tabset',
    controller:function($scope){

        var self = this;
        self.tabs = []
        self.add = function add(tab){
            self.tabs.push(tab);
            if(self.tabs.length === 1){
        tab.active = true;
        }
        }

        self.click = function click(selectedTab){
            angular.forEach(self.tabs,function(tab){
                 if(tab.active && tab !== selectedTab) 
                    tab.active = false;


        })
        selectedTab.active = true;
    }
},
link:function(scope,elem,attr,optionsCtrl){
        console.log(scope.newvar)
        scope.resetInput = function(){
            console.log("in resetInput")
            optionsCtrl.firstBox = "e"
            scope.item = "";
        }
        }
}
})

tabset template

<ul class="nav nav-tabs" ng-class="'{{newvar}}'" >
<li class='' ng-repeat="tab in tabset.tabs" >
    <a href="" ng-click="tabset.click(tab);resetInput();" ng-class='{"tab-active":tab.active,"tab-inactive":tab.active === false}'> {{tab.heading}}</a>
</li>
</ul>
<ng-transclude>
</ng-transclude>

回答1:

As you are using bindToController: true you could access you controller scope from link function 4th parameter which is controller, which will give you access to the directive controller this which is using controllerAs syntax in it.

link: function(scope, elem, attr, ctrl) {
    console.log(ctrl.newvar);
    //ctrl.newvar = attr.newvar;
}

Update

As you want to add class to your tab ul element. I think you shouldn't use ng-class there. ng-class used when conditionally show/hide any class in html. You should use plane {{}} interpolation in you class attribute. While accessing scope variable you need to use tabset. because you are using controllerAs syntax with its alias. I tried to add class with ng-attr-class but the class gets added but other two classes was getting removed nav nav tabs that's the reason behind using {{tabset.newvar}}.

Template

<ul class="nav nav-tabs {{tabset.newvar}}">
    <li class='' ng-repeat="tab in tabset.tabs" >
        <a href="" ng-click="tabset.click(tab);resetInput();" ng-class='{"tab-active":tab.active,"tab-inactive":tab.active === false}'> {{tab.heading}}</a>
    </li>
</ul>

Working Plunkr



回答2:

You can use scope.tabset to reference the controller and thereby give you access to your variable. Like this:

link: function(scope, elem, attr) {
    console.log(scope.tabset.newvar);
}