Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

docs($compile): refine explanation of =-bindings #13921

Closed
wants to merge 1 commit into from

Conversation

thorn0
Copy link
Contributor

@thorn0 thorn0 commented Feb 2, 2016

The current version of this paragraph is in many ways inaccurate and confusing.

@thorn0 thorn0 force-pushed the patch-10 branch 2 times, most recently from 1201468 to 893a273 Compare February 2, 2016 01:33
* `=*` 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
Copy link
Member

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
Copy link
Member

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.

Copy link
Contributor Author

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.

Copy link
Member

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:

  1. The expression is non-assignable and you try to assign to it.
  2. The attribut is missing and you try to assign to it.

I believe that the part in bold is missing from the description.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

@thorn0
Copy link
Contributor Author

thorn0 commented Feb 2, 2016

@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
Copy link
Member

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 :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@thorn0 thorn0 force-pushed the patch-10 branch 4 times, most recently from 5af6732 to b163540 Compare February 3, 2016 00:28
@Narretz
Copy link
Contributor

Narretz commented Feb 3, 2016

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
Copy link
Contributor

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.

@thorn0
Copy link
Contributor Author

thorn0 commented Feb 3, 2016

can you change all instances of widget to directive?

What about "component"? It's already called so a bit above:

{...} (an object hash): A new "isolate" scope is created for the directive's element. [...] This is useful when creating reusable components...

@Narretz
Copy link
Contributor

Narretz commented Feb 3, 2016

I would be okay with <my-component my-attr="parentModel">, but directive definition and directive's scope. Component is a rather specific term. I think the part you quoted shows that. Components imply a certain modularity, but directives can also add events etc. without being components.

The current version of this paragraph is in many ways inaccurate and confusing.
@thorn0
Copy link
Contributor Author

thorn0 commented Feb 3, 2016

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.

@Narretz
Copy link
Contributor

Narretz commented Feb 3, 2016

I think that's okay. The text is very information dense anyway. bindToController should make clear that it changes this behavior.

@thorn0
Copy link
Contributor Author

thorn0 commented Feb 3, 2016

I think bindings should get a higher level section of their own, like Transclusion. It can be done later though.

@gkalpak
Copy link
Member

gkalpak commented Feb 3, 2016

LGTM

gkalpak referenced this pull request in Narretz/angular.js Feb 3, 2016
@Narretz
Copy link
Contributor

Narretz commented Feb 3, 2016

@gkalpak Can you merge? Then I can rebase the one-way PR.

@gkalpak gkalpak closed this in 507cf31 Feb 3, 2016
gkalpak pushed a commit that referenced this pull request Feb 3, 2016
The current version of this paragraph is in many ways inaccurate and confusing.

Closes #13921
@gkalpak
Copy link
Member

gkalpak commented Feb 3, 2016

@Narretz: Merged.
(Backported to v1.4.x as 8a1f600.)

@thorn0 thorn0 deleted the patch-10 branch February 3, 2016 13:11
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants