I'm trying to wrap my head around scopes in angularjs, particularly when it comes to invoking callbacks on the module that is using a directive. I've found 3 different ways to accomplish the same thing and I'm trying to understand the pros/cons to each approach.
Given this plnkr
When is it appropriate to use &
, =
, or calling functions directly on the parent?
I prefer binding with the '=' sign, as there is less code required in the directive and in the module hosting the directive, but according to the documentation (Understanding Transclusion and Scopes) it seems that binding to callbacks with the &
is the preferred method, why?
Good question. These kinds of decisions should be made first from the perspective of trying to separate your concerns. So we have to eliminate calling a method on the parent scope - the directive has to know too much about the parent.
Next, we look at purpose. Callbacks are methods by definition. &
evaluates an expression in the context of the parent scope, while a bi-directional binding is just a variable name. &
is a lot more powerful and gives the user of your directive more flexibility. Sure, they could do this, like in your example:
<my-dir cb="callMe()"></my-dir>
But they could also do this:
<my-dir cb="myVar = false"></my-dir>
We don't have to pass in the name of a variable - it's any AngularJS expression. So the user of the component is free to react to your event in any way that suits them. Awesome!
But also, the directive can react to state changes. For example, you could check for a condition:
<my-dir cb="myVar"></my-dir>
And myVar
can evaluate to any value and your directive can be made aware anytime this changes and react accordingly. Instead of sharing a variable, you're sharing an expression. In this case, a bi-directional binding would work, but if the directive doesn't (and maybe shouldn't) change that variable, why do we need a two-way binding?
But again, it needn't be a variable. How about a expression that evaluates to true or false?
<my-dir cb="myVar == myOtherVar"></my-dir>
Our directive doesn't have to care how the parent scope arrives at a value - only what the value eventually is.
So we can use it for the parent scope to react to the directive or for the directive to react to the parent - all with flexible expressions. Neat.
So, =
is for ensuring data binding; it ensures that the scope where the directive was used and the directive itself stay in sync on a certain variable. &
allows for evaluating expressions in the context of the parent scope and for either the directive or the parent scope to react to potentially complex state changes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With