Angularjs, Directive, ampersand
angularjs, javascript
Solution
I study AngularJS, And today i run into weird case.
I don't understand why it's weird, it's just how angular.js works, and it's great!
this value looks like compressed function version...
You are right, If I run `Console.log(scope.done)` with a non minified code I get:
function (locals) {
return parentGet(scope, locals);
}
It's just the callback from compile.js source code:
case '&':
parentGet = $parse(attrs[attrName]);
isolateScope[scopeName] = function(locals) {
return parentGet(scope, locals);
};
As you can see, when using `scope: { done : "&"}` , angular parses the expression inside the attribute with `$parse` , and returns a function that when run will evaluate against the parent scope.
You must understand that this expression : `done="logChore(chore)"` will eventually run against the outer scope, but the outer scope may not have a `chore` property.
A good example is angular events directives like `ng-click="do($event)"` , the outer scope doesn't have a `$event` property, so where is it coming from?
Angular solves this problem by providing a locals object as the second argument which allows you to run an expression against an extended scope.
why can't i just do that: done(chore)?
The reason is because angular doesn't treat the attribute with `&` as a function, it treats it as an expression. Actually, you can put any expression inside that attribute, examples:
- `done = "logChore(chore); x = 1"`
- `done = "logChore(otherVar, chore)"`
- `done = "isLogged || logChore(chore)"`
- `done = "logChore(chore + 1)"`
When you invoke the function inside your directive, the argument you pass is not the same as the argument that will be passed into the controller's function, it's just happens that in your case it's the same.
What you do pass is a locals object that extends the scope in which the expression will be evaluated against.
Problem
I study AngularJS, And today i run into weird case, So this is the code: Plunker And there are some things i just can't explain: - If you can take a look at the value of `console.log(scope.done)` from the Plunker link above, This is the value `function (a){return l(e,a)}` this value looks like compressed function version, After i played with the code a bit i found that the above function return(and i assume) the call expression `logChore(chore)` we pass into done attribute `done="logChore(chore)"`, So by executing the `function (a){return l(e,a)}` we executing the `logChore(chore)` function ? - Another thing is why using object map `done({chore:chore})`, I do understand that the chore property value will be insert into the parameter with the same name `logChore(chore)`, But why can't i just do that: `done(chore)`. Well if some one can help me understand all of this i will be very thankful, Thank you all and have a nice day.