I have a custom navigation directive that needs an optional "disable" attribute, and I'm not sure if it's even possible.
In my main controller:
.controller('NavCtrl', ['UserResource','RoleResource'], function(UserResource,RoleResource){
var user = UserResource.getUser();
var roles = RoleResource.getRoles();
UserService.init(user, roles); //????
});
In my directive:
.directive('navItem', function(){
return{
restrict: 'A',
scope: {
text: '@',
href: '@',
id: '@',
disable: '&'
},
controller: function($scope, $element, $attrs){
$scope.disabled = ''; //Not sure I even need a controller here
},
replace: true,
link: function(scope, element, attrs){
scope.$eval(attrs.disable);
},
template: '<li class="{{disabled}}"><a href="{{href}}" id="{{id}}">{{text}}</a></li>'
}
});
In my HTML, I want to do something like this:
<div data-nav-item text="My Text" href="/mytemplate.html" id="idx"
disable="UserService.hasRole('ADMIN,BILLING') && someOtherFn(xxx) || ...">
One way of doing the same thing is like this http://jsfiddle.net/fFsRr/7.
You may replace the
todisableornot="rights[1]"
with your expression like thistodisableornot="UserService.hasRole('ADMIN,BILLING') && someOtherFn(xxx) || ..."
.Now as Mark Rajcok said the property
todisableornot
will be evaluated in the parent scope whenever you call that property. So<li ng-class="{adminRole:todisableornot()}"><a href="{{href}}" id="{{id}}">{{text}}</a></li>
will apply classadminRole
if thetodisableornot
property evaluates to true (in the context of parent scope).You can test this by changing the
$scope.rights =[true, false];
A more appropriate implementation for this specific problem would be to have an optional binding to a simple model property that has its value assigned from your complex statement. The Angular documentation repeatedly mentions that the best practice is to bind to model properties and not to functions. The "&" binding for directives is primarily useful for implementing callbacks, where you need to passing data from the directive to its parent.
Implementing an optional binding looks like this:
Code:
HTML:
Fiddle: http://jsfiddle.net/YHqLk/
You could make what you have work by chaning your $eval call to
because you need to evaluate the expression contained in
attrs.disable
in the parent scope, not the directive's isolate scope. However, since you are using the '&' syntax, it will evaluate the expression in the parent scope automatically. So just do the following instead:Fiddle.
Recently I faced this issue and found that I had multiple references (script tag) of the directive file in index.html. Once I removed these additional references the issue vanished.