Here is why I downvoted the answer.
First, you should never use '=' to pass function references to directives.
'=' creates two watches and uses them to ensure that both the directive scope and the parent scope references are the same (two-way binding). It is a really bad idea to allow a directive to change the definition of a function in your parent scope, which is what happens when you use this type of binding. Also, watches should be minimized - while it will work, the two extra $watches are unnecessary. So it is not fine - part of the down vote was for suggesting that it was.
Second - the answer misrepresents what '&' does. & is not a "one way binding". It gets that misnomer simply because, unlike '=', it does not create any $watches and changing the value of the property in the directive scope does not propagate to the parent.
According to the docs:
& or &attr - provides a way to execute an expression in the context of
the parent scope
When you use & in a directive, it generates a function that returns the value of the expression evaluated against the parent scope. The expression does not have to be a function call. It can be any valid angular expression. In addition, this generated function takes an object argument that can override the value of any local variable found in the expression.
To extend the OP's example, suppose the parent uses this directive in the following way:
<my-component foo="go()">
In the directive (template or link function), if you call
foo({myVal: 42});
What you are doing is evaluating the expression "go()", which happens to call the function "go" on the parent scope, passing no arguments.
Alternatively,
<my-component foo="go(value)">
You are evaluating the expression "go(value)" on the parent scope, which will is basically calling $parent.go($parent.value)"
<my-component foo="go(myVal)">
You are evaluating the expression "go(myVal)", but before the expression is evaluated, myVal will be replaced with 42, so the evaluated expression will be "go(42)".
<my-component foo="myVal + value + go()">
In this case, $scope.foo({myVal: 42}) will return the result of:
42 + $parent.value + $parent.go()
Essentially, this pattern allows the directive to "inject" variables that the consumer of the directive can optionally use in the foo expression.
You could do this:
<my-component foo="go">
and in the directive:
$scope.foo()(42)
$scope.foo() will evaluate the expression "go", which will return a reference to the $parent.go function. It will then call it as $parent.go(42). The downside to this pattern is that you will get an error if the expression does not evaluate to a function.
The final reason for the down vote was the assertion that the ng-event directives use &. This isn't the case. None of the built in directives create isolated scopes with:
scope:{
}
The implementation of '&foo' is (simplified for clarity), boils down to:
$scope.foo = function(locals) {
return $parse(attr.foo)($scope.$parent, locals);
}
The implementation of ng-click is similar, but (also simplified):
link: function(scope, elem, attr) {
elem.on('click', function(evt) {
$parse(attr.ngClick)(scope, {
$event: evt
}
});
}
So the key to remember is that when you use '&', you are not passing a function - you are passing an expression. The directive can get the result of this expression at any time by invoking the generated function.