-
Notifications
You must be signed in to change notification settings - Fork 6.7k
fix(tooltip): update placement on content change #1415
Conversation
Added some tests to count on @pkozlowski-opensource LGTM :-) Any objections merging? |
@bekos I would love to see if we can avoid using $timeout which will slow things down by putting browser into rendering mode and triggering a digest loop in JS execution context. Why is the $timeout needed here? Is it because size / position is not updated by a browser yet? In this case we can trigger reflow by reading one of the size params. What I'm trying to say here is that $timeout should be the last resort... |
@pkozlowski-opensource When $observe is fired by the dynamic content change of the attribute, the actual content of the tooltip has not changed yet. This will happen on the next digest cycle. That's why I wire the position update, to also be fired in the next digest cycle. I hope this makes sense :-) |
@pkozlowski-opensource By reading one of the size params you mean to |
@pkozlowski-opensource (Too much noise! sorry) What about using the |
@pkozlowski-opensource Updated to |
Another alternative (that I found while working on #1455) is to force one digest cycle on the tooltip's isolate scope by doing |
@chrisirhc Good point. I will try to compare them, but I believe that for both ways the performance impact is too small, and is only experienced in edges cases, since in the normal usage there is no performance hit. We can also fire the content update only once every 100ms, or 200ms if it'too slow, but we are adding too much complexity for an edge case bug :-) |
@bekos actually it's quite different because $timeout causes a digest cycle on the $rootScope so all watchers in all scopes will run while doing scope.$digest just causes the watchers in this isolate scope to run. The difference impact on performance is depends on the number of watchers and the complexity of the rest of the application (out of this directive). Hence, I would advise against using a $timeout. |
@chrisirhc I call |
Oh yes, right. I just find $timeout logic makes the logic more difficult to test and timers should be avoided if possible especially if the purpose isn't to wait a specific amount of time. In this case, waiting for the content is actually waiting for a $digest cycle, not waiting time to pass. You're right that the difference probably isn't huge if you don't invoke apply. |
@chrisirhc |
Have you tried $evalAsync? Heh, I think that should work in this case. Update: I thought about this again as I was looking through AngularJS core's $animate codebase. Perhaps $timeout without invoking apply wouldn't be so bad after all. If $evalAsync doesn't work, your $timeout solution is a good idea. |
@chrisirhc Nice! 👍 |
@chrisirhc Just saw your update. |
Excellent! I wasn't 100% certain it would work as I haven't actually tried it but now we know! 😄 |
Since the recompute of position is a heavy calculation and given that this happens only when tooltip is visible, ie position is already calculated, we can reuse it to update the position when widht/height changes. Closes angular-ui#96
@pkozlowski-opensource Is there something that still bothers you? |
@bekos @chrisirhc yep, in fact yes. In fact I'm pondering bigger rewrite for tooltips / popovers to be able to easily support templates for content and manual triggers. So I would like to just take a bit more time to understand the current implementation and confront it with what I've got on my mind. Give me few more days, it is not forgotten :-) |
@pkozlowski-opensource No worries! |
After #1455, it's actually okay to update the position on any change of content or even just on any digest call on the tooltip's scope. This is because the tooltip's scope only exists when it's visible. As such, there can only be at most one tooltip visible and only one watcher that's always updating the tooltip to fit the content. (Adding reference to #96 on this PR for tracking) |
Closing this PR due to no activity. |
Resolved via #3435 . |
Since the recompute of position is a heavy calculation and given
that this happens only when tooltip is visible, ie position
is already calculated, we can reuse it to update the position when
widht/height changes.