-
Notifications
You must be signed in to change notification settings - Fork 27.4k
docs($compile): refine explanation of =
-bindings
#13921
Conversation
1201468
to
893a273
Compare
* `=*` or `=*attr` (`=*?` or `=*?attr` if the property is optional). | ||
* * `=` or `=attr` - set up a bidirectional binding between a local scope property and an expression | ||
* passed via the attribute `attr`. The expression is evaluated in the context of the parent scope and | ||
* can be either an assignable expression or a literal value. If no `attr` name is specified then the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you are at it, it might be a good idea so somehow mention that if a non-assignable expression is passed, then $compile:nonassign
will be thrown when trying to assign to it.
* attribute name is assumed to be the same as the local name. Given `<widget my-attr="parentModel">` | ||
* and the widget definition `scope: { localModel:'=myAttr' }`, the property `localModel` on the widget's | ||
* scope will reflect the value of `parentModel` on the parent scope. Changes to `parentModel` will be | ||
* reflected in `localModel` and vice versa. If the attribute doesn't exist, an exception will be thrown |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I think it will only throw if you try to assign and the expression is non-assignable or the attribute is missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. I believe that's exactly what I wrote.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I was clear. I meant it will throw if:
- The expression is non-assignable and you try to assign to it.
- The attribut is missing and you try to assign to it.
I believe that the part in bold is missing from the description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see. You're right. But is it worth going into these details when all we need here is just to give a notion of optional bindings? Won't it overcomplicate the explanation?
However, I found another interesting detail missing from this text. Namely, when the expression is an object or array literal, the watch is deep.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean, if the attribute is optional, please mark it as such. The idea should be like this. It doesn't really matter how and when exactly it fails if you didn't mark it.
@gkalpak pls have a look |
* `=*` or `=*attr` (`=*?` or `=*?attr` if the property is optional). | ||
* * `=` or `=attr` - set up a bidirectional binding between a local scope property and an expression | ||
* passed via the attribute `attr`. The expression is evaluated in the context of the parent scope and | ||
* must be either an assignable expression or a literal value. If no `attr` name is specified then the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not required to be an assignable expression. Only if you try to assign to it :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
5af6732
to
b163540
Compare
Looks good. One suggestion, can you change all instances of widget to directive? I widget is a relict of very old times, iirc, back before the term directive was introduced. |
* doesn't exist, an exception ({@link error/$compile/nonassign `$compile:nonassign`}) will be | ||
* thrown on discovering changes to the local value since it'll be impossible to sync it with the | ||
* parent scope in this case. By default, the {@link ng.$rootScope.Scope#$watch `$watch`} method is | ||
* used for tracking changes, and the equality check is done by reference. However, if an object |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I find it clearer to say that the equality check is based on object identity. I guess it means the same though.
What about "component"? It's already called so a bit above:
|
I would be okay with |
The current version of this paragraph is in many ways inaccurate and confusing.
OK. Eliminated widgets and replaced 'by reference' with 'based on object identity'. But I also don't like that it says "local scope property", "property of the directive's scope" everywhere whereas the same binding mechanism is used for controllers. |
I think that's okay. The text is very information dense anyway. bindToController should make clear that it changes this behavior. |
I think bindings should get a higher level section of their own, like Transclusion. It can be done later though. |
LGTM |
@gkalpak Can you merge? Then I can rebase the one-way PR. |
The current version of this paragraph is in many ways inaccurate and confusing. Closes #13921
The current version of this paragraph is in many ways inaccurate and confusing.