-
Notifications
You must be signed in to change notification settings - Fork 27.5k
An isolated-scoped-directive's ng-transclude loses parent scope when inside of an ng-repeat. #1809
Comments
This issue still exists in 1.0.5. Updated fiddle: http://jsfiddle.net/nCfBA/1/ I'd be happy to fix this, but don't know where to begin. |
+1 |
+1 |
I'm still happy to try and fix this =). |
I am facing exactly the same issue. I think the problem is the $transclude function that keeps the reference of outer scope. I have created a new directive (replacement for ng-transclude) that uses correct scope. angular.module("my").directive('myTransclude', function() {
return {
compile: function(tElement, tAttrs, transclude) {
return function(scope, iElement, iAttrs) {
transclude(scope.$new(), function(clone) {
iElement.append(clone);
});
};
}
};
}); However, I am not sure whether this is the correct solution but at least it's working fine for our use cases. |
Wow, thanks cristatus. That fixed my problem also where I had two directives on an element and one of those directives ( directive( 'verticalCenter', function () {
return {
restrict : 'AC',
template : ' \
<div style="display: table; width: 100%; height: 100%"> \
<div style="display: table-cell; vertical-align:middle;" my-transclude> \
</div>\
</div>',
transclude : true,
scope: false
}
}); |
+1 |
Looks like it's fixed in master 45f9f62 |
Previously it was possible to get into a situation where child controller was being instantiated before parent which resulted in an error. Closes #2738
Not sure if it is: http://jsfiddle.net/33jQz/ |
@petebacondarwin, I'm also a "victim" of this. Do you know of any quick fix for this? |
@gustavohenke Did you try the quick fix from @cristatus? |
+1 |
it's still there. ng-transclude with ng-if inside of directive with transclude: true & isolate scope. |
I was able to recreate this with ng-if: and I can confirm that this line (https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js#L93) within ng-if is calling scope.$new() on a child scope of my directive, and not of the parent scope as you would expect. I bet that's what's happening within ngRepeat as well. Here is how I overcame this. It sucks, but it works:
|
+1 |
Plunked a workaround for this, description can be found on stackoverflow. |
+1 |
I have a fix for this at #7499 |
@petebacondarwin how would you go about making the repeated item also accesible inside the transcluded scope? This would allow writing custom "repeat" directives effortlessly (delegating to Thanks! |
@gabrielmaldi - you cannot do this with ng-transclude. You could hack it by calling the transclude function yourself and mapping in local properties onto the new scope...
|
@petebacondarwin thanks, I followed your advice and assembled this: http://jsfiddle.net/gabrielmaldi/w2YNf But there's a problem: if you replace the So I came up with this solution: http://jsfiddle.net/gabrielmaldi/FHy4z Here I'm messing with scopes, creating a new "transcluded" (doesn't get external HTML, just scope inheritance) one and attaching it to the parent of the element with the I'd really appreciate to hear what you have to say about this approach: is it too hackish or farfetched? can this cause any leaks when destroying scopes (introducing the new "transcluded" scope like this)? Thanks again for your help! |
Actually I think that transclude probably should play not part in this kind of directive. |
That makes sense and I acknowledge that I'm abusing transclusion a little. I like the approach of just injecting the template HTML inside |
@petebacondarwin You're solutions are quite elegant, but they don't cover every case. ie. my case, where I use a template URL for my template. The compile function doesn't have access to either the template, or the URL for the template. If it did I could just attach tElement to my element inside ng-repeat and be good to go. Any ideas on how to solve this? So for example, my directive has:
with directive template like (but a lot more html warranting the separate template file):
and html:
I understand using compile etc. It's actually a quite clever solution, however I can't appear to use that solution, because my template is in a separate file and can't be simply written in the compile function. |
Your compile fn is called after we fetch the template. So you do have access to the template from compile fn. |
where? How would I access that template? This is very intriguing! :D |
It should already have been added to the directive element
|
so... first, second, third argument to compile? perhaps it is found in one of the injected modules?
|
@petebacondarwin @gabrielmaldi Any word on the proper way to make this method (compile function injecting HTML into an ng-repeat or other transcluding directive) work inside a directive with isolate scope? |
@petebacondarwin @gabrielmaldi By means of example, here's what I'm doing currently: app.directive('transcludeIntoRepeat', function($compile) {
return {
restrict: 'E',
template: '<div></div>',
replace: true,
transclude: true,
scope: {items: '='},
link: function(scope, element, attrs, ctrl, transclude) {
transclude(scope, function(clone) {
var template = angular.element('<div ng-repeat="item in items"></div>');
template.append(clone);
element.append($compile(template)(scope));
});
}
}); To add a level of complexity, yes I'm using a template and yes Here's a plunker: http://plnkr.co/edit/aBHOFnpy5U4Eh3R5yjhD?p=preview I can't help but think I'm going about this the wrong way... |
@wtfribley I'm currently using this approach: http://jsfiddle.net/gabrielmaldi/FHy4z I explained it a bit here:
|
Any hints on how to achieve this(access scope) with multi slot transclusion of angularJS 1.5? |
@durga-telsiz, you are unlikely to get any help on this thread. This is issue is very old (v1.0.x) and closed. For general support/usage question, you can use one of the support channels. If you think you have found a bug in Angular or want to request a feature, please submit a new issue (if one does not already exist). |
The fiddle: http://jsfiddle.net/nCfBA/
To reproduce in short: 1) transcluded element needs to reference something in its parent scope, 2) directive's template needs to transclude inside of an ng-repeat. The transcluded element cannot read its original parent scope.
If included outside of the ng-repeat it can read the value in the parent scope (as one would expect).
I posted this to a google group (https://groups.google.com/forum/#!topic/angular/az8_uNV7KyE) but was directed to post it as a possible bug.
I don't mind trying to tackle and fix this, but I really have no idea where to start looking.
The text was updated successfully, but these errors were encountered: