In this video, Aviv Ben-Yosef explains how Angular & bindings work. Understand how function parameters are passed, and why the syntax looks the way it does.
- [Voiceover] Angular has several cases where the syntax trips you up, or where it's just not clear what should be used. I've seen people get frustrated time after time about the ampersand binding for passing functions to directives or components. Let's understand exactly how it works. First, here's an example component that has one of these ampersand bindings. As you can see, the component has a simple binding called callback. The usage of this component would look something like this.
This means that whenever the toggle directive would call the callback binding, the myCallback function on the caller's controller would be triggered. Now, what what everyone gets mixed up with, when using ampersand bindings, is functions that have parameters. Say that the callback wants to pass an argument. The component would be created like so, but inside the component, the calling syntax would look quite foreign the first time you see it.
Simply trying to invoke it like a regular function would not work. Arguments have to be passed inside a value object. What's going on? Technically speaking, when using the ampersand binding, Angular doesn't just do two-way bindings the regular way. It takes the expression, in this case, myCallback value, and saves it. When called, Angular evaluates that expression on the parent scope.
This is because, when using ampersand, it's possible to pass something other than function calls, even though that's what developers actually do, 99% of the time. It is possible to pass an expression and not just a function and that would still work. Because the ampersand binding is so generic, it doesn't really have a notion of function parameters. The expression could be anything. When passing at the object, it is actually a mapping of local variables to override.
Angular takes the expression and evaluates it in the parent scope, but the values added as locals, take priority over values already defined in the parent scope. This was done so that it would be possible to pass expressions instead of functions to anything in Angular. Have you ever used ng-click with an expression, instead of a function call? Those work using a similar mechanism. The core team wanted us to have this flexibility and the price is that we have to invoke functions in a way that feels a bit clunky.
But remember, you're not really calling a function. You're evaluating an expression and supplying it with values.
- Speeding up ng-repeat with track by
- One-time binding
- Using ng-change instead of $watch
- Understanding & binding
- Understanding @ binding
- Creating promises without $q.defer()
- Handling circular dependencies
- Multiple transclusion
- Turning URLs in paragraphs into safe links