You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
Repository navigation
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
(reposting from (comment)[https://github.com//pull/7387#issuecomment-54363122])
JSFiddle example here – in the second test, the nested transclude is ignored.
It seems to lose the transcluded content when the ng-transclude is applied to the same element as the nested directive within the outer directive's template.
It works if the ng-transclude is applied to a wrapper element inside the nested directive (but then you're left with an irritating wrapper element).
I think there's a conceptual mismatch between how the fiddle assumes transclusion to work and how it actually works.
In short, transclusion determines the content that will be transcluded during compilation, whereas the transclusion itself is actually done during linking. Whether it’s done with ng-transclude or by calling the bound transclusion function some other way, doesn’t really matter.
The ng-transclude on u is never done because the element is removed before that.
For the “workaround” case in the fiddle the mental model holds, because transclude: true and ng-transclude are never used on the same element, which is where the confusion begins.
There’s probably a way to fix this. To me it seems like it would mean a way for $compile to know not only where transclude: true is enabled, but also where transclusion is actually being applied. I don’t see away to do this without adding complexity and I feel like added complexity is the last thing $compile needs. :)
@teropa thanks for the break down of why this is happening. However, while the jsbin's mental model might not match the current implementation, it does match the expectation of what the correct behavior would be -- this is kind of the definition of a "bug".
If you have a directive like outer with this template:
<ahref="#"><innerng-transclude></inner></a>
It will work fine if <inner> does not use transclusion
It will be broken if <inner> uses transclusion
This forces <outer> to have intimate implementation knowledge of <inner>, which is unreasonable. <inner> should be able to refactor their code to use transclude without breaking <outer>.
Activity
IgorMinar commentedon Sep 3, 2014
@vojtajina could you take a look at this one please?
fix($compile): render nested transclusion at the root of a template
fix($compile): render nested transclusion at the root of a template
fix($compile): render nested transclusion at the root of a template
fix($compile): render nested transclusion at the root of a template
fix($compile): render nested transclusion at the root of a template
tbosch commentedon Sep 15, 2014
Reopening as the commit was reverted.
5 remaining items
fenduru commentedon Feb 5, 2015
👍 ran into this today
teropa commentedon Jun 12, 2015
I think there's a conceptual mismatch between how the fiddle assumes transclusion to work and how it actually works.
In short, transclusion determines the content that will be transcluded during compilation, whereas the transclusion itself is actually done during linking. Whether it’s done with
ng-transcludeor by calling the bound transclusion function some other way, doesn’t really matter.So with these directives:
The fiddle’s assumption seems to be that this would happen with the when applied to
<outer>✔</outer>:Outer’s content
"✔"is stored for later transclusionOuter’s content is replaced with its template.
Inner’s content is replaced with
"✔"from outer’s transclusion in step 1Inner’s content, now
"✔"is stored for later transclusionInner’s content is replaced with its template.
u’s content is replaced with
"✔"from the inner transclusion in step 4However, what actually happens is:
At compilation time:
Outer’s content
"✔"is stored for later transclusionOuter’s content is replaced with the template.
Inner’s content,
""is stored for later transclusionInner’s content is replaced with its template
At linking time
The ng-transclude on inner is applied. It is
""from step 3.The
ng-transcludeonuis never done because the element is removed before that.For the “workaround” case in the fiddle the mental model holds, because
transclude: trueandng-transcludeare never used on the same element, which is where the confusion begins.There’s probably a way to fix this. To me it seems like it would mean a way for $compile to know not only where
transclude: trueis enabled, but also where transclusion is actually being applied. I don’t see away to do this without adding complexity and I feel like added complexity is the last thing $compile needs. :)fenduru commentedon Jun 12, 2015
@teropa thanks for the break down of why this is happening. However, while the jsbin's mental model might not match the current implementation, it does match the expectation of what the correct behavior would be -- this is kind of the definition of a "bug".
If you have a directive like outer with this template:
<inner>does not use transclusion<inner>uses transclusionThis forces
<outer>to have intimate implementation knowledge of<inner>, which is unreasonable.<inner>should be able to refactor their code to usetranscludewithout breaking<outer>.teropa commentedon Jun 12, 2015
@fenduru Agreed, this is a leaky abstraction at the moment.
petebacondarwin commentedon Jul 30, 2015
@teropa - do you have any ideas of how to fix this? I have no capacity and this is a fairly uncommon corner case. Assigning to the Ice Box for now.