Is there any way to transclude some content into a directive without adding extra elements.
For example
directive:
{
scope: {
someParam: "="
},
link: function(scope, element, attrs){
//do something
},
transclude: true,
template:'<div ng-transclude></div>'
}
source html:
<div my-directive some-param="somethingFromController">
my transcluded content: {{somethingElseFromController}}
</div>
With this example an extra div gets added to the markup. Normally this would be fine but I'm trying to use this directive inside a table so adding a div tag screws things up.
I also tried not specifying transclude
or template
which gets rid of the extra div tag but now {{somethingElseFromController}}
cannot be found as the "transcluded" content is in an isolated scope. I know I could just get the parameters for my directive from the attrs object in the linking function instead of creating an isolated scope but I'd rather avoid needing to evaluate strings with scope.$apply().
Anyone know how to accomplish this? Thanks!
What @Vakey answered is what I was searching for.
But as today, the Angular documentation says:
The transclude function that is passed to the
compile
function is deprecated, as it e.g. does not know about the right outer scope. Please use the transclude function that is passed to the link function instead.
So I used instead the controller
(for the moment) and its $transclude
function, as part of the example shown on the $compile documentation:
controller: function($scope, $element, $transclude) {
var transcludedContent, transclusionScope;
$transclude(function(clone, scope) {
$element.append(clone);
transcludedContent = clone;
transclusionScope = scope;
});
},
This actually is possible with Angular. Directives such as ng-repeat do this. Here is how you do it:
{
restrict: 'A',
transclude: true,
compile: function (tElement, attrs, transclude) {
return function ($scope) {
transclude($scope, function (clone) {
tElement.append(clone);
});
};
}
};
So what's going here? During linking, we are just appending the clone, which is the element we are trying to transclude, into the directive's element. Angular will apply $scope onto the clone element so you can do all the angular goodness inside that element.
To elaborate on @rob's post...
Transclusion requires that Angular creates an element that is a clone of the content of whatever tag the directive is/lives on... If the content is text, it will wrap it in a span.
This is so it has a DOM element to apply the scope to when $compile is called.
So, basically transclude adds an element for the same reason you can't $compile('plain text here {{wee}}')
.
Now, you can do something sort of like what you're trying to do with $interpolate, which allows you to apply a scope to bindings in a string like "blah {{foo}}".... but since I'm really not sure what you're trying to do, I can't really give you a specific example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With