Reputation: 40337
I have 2 attribute directives (restrict is set to 'A' on both), dir1
and dir2
that are defined in two different modules. In one app (that includes both these modules), we have an element where one of these 2 directives could get added. We currently set things up so that dir1
is the default for this element, but we want a way to have dir2
"override" this directive.
The element we want to do this with is part the template of another directive, parentDir
, so my first thought was adding some functionality to the compile
function for parentDir
. The template for parentDir
would have in it <div class="myElement" dir1="{{data}}"></div>
and then the compile function would look something like this:
function(tElement, tAttrs) {
if ("true" == tAttrs.useDir2)
{
var myElement = tElement.find("div.myElement");
myElement.removeAttr("dir1");
myElement.attr("dir2", "{{data}}");
}
return function (scope, element, attrs) {
// link stuff
}
}
where useDir2
would be an attribute on the parentDir
directive. This would work fine, but the value for useDir2
is an interpolated value, so I wouldn't be looking at the value I want with tAttrs.useDir2
.
I thought about setting priorities on the 2 directives, but then each directive would have to know the other's priority to make sure they related to each other correctly. You wouldn't want someone to come into one module and change the priority for something else, and break this functionality. Since the two directives are in different modules, I want them to be completely ignorant of each other.
I hope I've explained my problem clearly enough. I'm just not sure how to go about doing this, and think I may be missing some easy way to do this. Thanks.
Upvotes: 1
Views: 139
Reputation: 23394
I believe you will need to do something like you proposed. If you need it to be defined in run-time (i.e. by the controller), in your linking function, $observe
the attribute and then change and recompile the element contents when the value is changed. Something like this:
app.directive('parentDir', function($compile) {
return {
link: function(scope, element, attr) {
attr.$observe('parentDir', function(value) {
var div = angular.element('<div ' + value + '></div>');
element.find('div').remove();
element.append(div);
$compile(div)(scope);
});
},
template: '<input type="checkbox" ng-model="val"/> Use directive 2: ' +
'<div></div>'
};
});
I made a fiddle.
Naturally, I simplified the parentDir, you might need to cache the original state of the DOM, so you can safely recompile it.
Upvotes: 1