Binding A Single Directive To Multiple Priorities On The Same Element In AngularJS
Last night, I was looking through the AngularJS source code when I noticed that the ngInclude directive was defined twice. At first, I had no idea what to make of this craziness; but then, I realized that each version of the directive was given a different priority. I had no idea that this was possible in AngularJS - giving a single directive different priorities; but, upon further investigation, it totally works!
To test this multi-priority directive feature, I wanted to created a directive that would execute on either "side" of the native ngRepeat directive. This would allow the same AngularJS directive to have access to the ngRepeat element both before and after transclusion.
Since ngRepeat executes with priority 1000, I'm going to define a single directive that uses priorities 1001 (before ngRepeat) and 999 (after ngRepeat).
As you can see, the directive bnFriends, provides a compile and a link function that will run before the ngRepeat priority; and, it provides a link function that will run after the ngRepeat priority. Furthermore, the bnFriends directive defines a controller that allows both priorities of the directive to maintain communication.
When we run the above code, we get the following console output:
High priority compiling
High priority linking
Low priority linking [ 0 ][ hello world ]
Low priority linking [ 1 ][ hello world ]
Low priority linking [ 2 ][ hello world ]
Low priority linking [ 3 ][ hello world ]
As you can see, the "high priority" version of the directive compiled and linked once before the ngRepeat directive; then, the "low priority" version of the same directive linked after the ngRepeat directive, running once per cloned and linked element.
The benefit of this might not be obvious; but, when I saw this, I immediately thought of my ngRepeat-optimized "switch" directive that needed access to both "sides" of the ngRepeat directive. Being able to define the same directive at multiple priorities would certainly simplify such approaches.
AngularJS, you're always surprising me with your awesome sauce!
Want to use code from this post? Check out the license.
FYI, I tested this back to AngularJS 1.0.8 and it seems to work nicely.
This is awesome Ben, 1001 and 999 ftw ;)
Thanks guys! Glad you like. Reading through the AngularJS source code is [often] like reading a foreign language :) I'm sure there's all sorts of interesting techniques that they use that I can't even being to understand.
This is really cool Ben. Thanks for sharing!
Thanks my man! Hopefully we can come up with some good applications for this kind of stuff in InVision!
This is probably one of the best mentions of this topic I've seen in quite a while. It's obvious that your knowledge of the subject is deep and this made for a very interesting read.
Here is a real-world application for this approach, which is more of a performance optimization than anything else:
As with this blog post, it binds to both "sides" of the native ngRepeat directive.
Thank you so much! I really appreciate the kind words :D
Hi Ben !!!
I was working on the same code.But I really didn't find solution for my queries.Is it possible to to access different controllers information in single directive using angular js........