-
Notifications
You must be signed in to change notification settings - Fork 27.5k
Link fn of a replace+transclude directive runs before transclusion takes place #3558
Comments
http://plnkr.co/edit/PFtqmLwPKX4UJbLOEGtg?p=preview Your example was broken |
@bobslaede Thanks for the fix. |
I can confirm this bug — my directives became broken after upgrade from 1.1.5 to 1.2.0-rc1. |
It looks like the compile order has changed (maybe here 683fd71). If I transclude a directive that uses the same parent controller as my directive does (e.g. I wrap an <input> in a custom <formfield> directive and both |
I don't think it is intended behavior, when the dom is not "ready" for the post-link function. |
Yes I guess you are right, the dom has to be ready in the post-link function. |
I'm guessing its the $scope.$evalAsync method call. There's no way to know when that is done. |
Changing $evalAsync to just $eval makes everything available in both pre and post link. Maybe there's some performance gain here? Somebody must know :) |
Do you talk about this 683fd71#L0R56 |
Yeah, that one |
So I guess @IgorMinar should know :) |
Changing $evalAsync doesn't help that bug with ng-include sadly... |
I just had a chance to run the unit tests, they fail with the "fix". |
This isn't solving the underlying problem, but I was able to get around this by wrapping my link function contents in a $timeout(). In my case, my template contains a // Fails
link: function(scope, elm, attrs) {
console.log(elm.find('code').text()); // Blank
}
// Works
link: function(scope, elm, attrs) {
$timeout(function() {
console.log(elm.find('code').text()); // Expected text
}, 0);
} EDIT: Just to clarify, I'm not proposing this as a solution, just a temporary work around. |
Why has it been closed? Is there a fix? (The timeout trick doesn't seem to be too convincing). |
Yep — timeout is a hacky workaround indeed, please reopen the issue. |
Sorry, I didn't intend to close the issue. |
previously the translusion was appended the the ngTranslude element via $evalAsync which makes the transluded dom unavailable to parent post-linking functions. By appending translusion in linking phase, post-linking functions will be able to access it.
I wonder if rc2 fixes it with this: |
Looks like @bobslaede 's example still fails (I updated below). Transcluded content is in the DOM during post-link when using 1.1.5, but not when using 1.2.0rc1 nor 1.2.0-rc.2: |
I can confirm that the bug is still present in 1.2.0-rc2. |
It's important to note that the issue affects only directives that have both |
This should get fixed by #3927 |
#3927 didn't fix this, we need a different fix. I'm working on it. |
previously the compile/link fns executed in this order controlled via priority: - CompilePriorityHigh, CompilePriorityMedium, CompilePriorityLow - PreLinkPriorityHigh, PreLinkPriorityMedium, PreLinkPriorityLow - link children - PostLinkPriorityHigh, PostLinkPriorityMedium, PostLinkPriorityLow This was changed to: - CompilePriorityHigh, CompilePriorityMedium, CompilePriorityLow - PreLinkPriorityHigh, PreLinkPriorityMedium, PreLinkPriorityLow - link children - PostLinkPriorityLow, PostLinkPriorityMedium , PostLinkPriorityHigh Using this order the child transclusion directive that gets replaced onto the current element get executed correctly (see issue angular#3558), and more generally, the order of execution of post linking function makes more sense. The incorrect order was an oversight that has gone unnoticed for many suns and moons. (FYI: postLink functions are the default linking functions) BREAKING CHANGE: the order of postLink fn is now mirror opposite of the order in which corresponding preLinking and compile functions execute. Very few directives in practice rely on order of postLinking function (unlike on the order of compile functions), so in the rare case of this change affecting an existing directive, it might be necessary to convert it to a preLinking function or give it negative priority (look at the diff of this commit to see how an internal attribute interpolation directive was adjusted). Closes angular#3558
@IgorMinar - documentation about this "issue/fix/breaking change" says:
Look at my case: So, I had this "quick & dirty" super-simple directive coupled with ngPattern working fine with rc.2, and suddenly not working anymore with rc.3. The directive adds a After comprehending the issue, it became extremely easy to fix the situation. Anyway, I must question the documentation due to:
Anyway, strictly considering my case, the rc.3 behaviour is better, since the ngPattern regexp validation is applied into the parsed value, instead of the formatted value - it means I can write the regexp to the model value - not the modified view value. So, my "fix" for rc.3 consists in change a single character in my regular expression (better than doing something to revert to the previous behaviour). Someone else may befenit of this testimonial I've just shared right here, but maybe we can also consider enhancing this breaking change related documentation... Thanks! |
previously the compile/link fns executed in this order controlled via priority: - CompilePriorityHigh, CompilePriorityMedium, CompilePriorityLow - PreLinkPriorityHigh, PreLinkPriorityMedium, PreLinkPriorityLow - link children - PostLinkPriorityHigh, PostLinkPriorityMedium, PostLinkPriorityLow This was changed to: - CompilePriorityHigh, CompilePriorityMedium, CompilePriorityLow - PreLinkPriorityHigh, PreLinkPriorityMedium, PreLinkPriorityLow - link children - PostLinkPriorityLow, PostLinkPriorityMedium , PostLinkPriorityHigh Using this order the child transclusion directive that gets replaced onto the current element get executed correctly (see issue angular#3558), and more generally, the order of execution of post linking function makes more sense. The incorrect order was an oversight that has gone unnoticed for many suns and moons. (FYI: postLink functions are the default linking functions) BREAKING CHANGE: the order of postLink fn is now mirror opposite of the order in which corresponding preLinking and compile functions execute. Very few directives in practice rely on order of postLinking function (unlike on the order of compile functions), so in the rare case of this change affecting an existing directive, it might be necessary to convert it to a preLinking function or give it negative priority (look at the diff of this commit to see how an internal attribute interpolation directive was adjusted). Closes angular#3558
previously the compile/link fns executed in this order controlled via priority: - CompilePriorityHigh, CompilePriorityMedium, CompilePriorityLow - PreLinkPriorityHigh, PreLinkPriorityMedium, PreLinkPriorityLow - link children - PostLinkPriorityHigh, PostLinkPriorityMedium, PostLinkPriorityLow This was changed to: - CompilePriorityHigh, CompilePriorityMedium, CompilePriorityLow - PreLinkPriorityHigh, PreLinkPriorityMedium, PreLinkPriorityLow - link children - PostLinkPriorityLow, PostLinkPriorityMedium , PostLinkPriorityHigh Using this order the child transclusion directive that gets replaced onto the current element get executed correctly (see issue angular#3558), and more generally, the order of execution of post linking function makes more sense. The incorrect order was an oversight that has gone unnoticed for many suns and moons. (FYI: postLink functions are the default linking functions) BREAKING CHANGE: the order of postLink fn is now mirror opposite of the order in which corresponding preLinking and compile functions execute. Very few directives in practice rely on order of postLinking function (unlike on the order of compile functions), so in the rare case of this change affecting an existing directive, it might be necessary to convert it to a preLinking function or give it negative priority (look at the diff of this commit to see how an internal attribute interpolation directive was adjusted). Closes angular#3558
I'm unable to access transcluded elements in a link function. The behavior has changed since 1.1.5. See http://plnkr.co/edit/WvGAlByx1771wurPbWXA?p=preview and compare the result with the commented 1.1.5 script
element.children();
should contain the transcluded elements like the `h2' tags:The text was updated successfully, but these errors were encountered: