Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with property binding reevaluation with a template reference variable #22108

Closed
junghoocho opened this issue Feb 9, 2018 · 8 comments

Comments

@junghoocho
Copy link

junghoocho commented Feb 9, 2018

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[X] Bug report  
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

Expected behavior

In a template I include the following HTML code:

<input type ="text" #query><input type ="submit" [disabled]="!query.value">

I expect the the submit button is disabled by default, but when I type something into the input box, it gets enabled since the property binding will be reevaluated in every event cycle. But that is not what is happening. The button stays disabled.

If I change the above code to the following,

<input type ="text" (input)="0" #query><input type ="submit" [disabled]="!query.value">

and add an explicit event binding (which has nothing to do with the template variable itself), it behaves as intended. I think there is an overaggressive optimization is going on, which is not in compliance with what is stated in this page: https://angular.io/guide/architecture

"Angular processes all data bindings once per JavaScript event cycle, from the root of the application component tree through all child components."

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


Angular version: 1.6.7


Browser:
- [X] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [X] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: 9.3.0  
- Platform: Mac 

Others:

@Toxicable
Copy link

Seeing a Stack blitz reproduction would be great https://stackblitz.com/fork/angular-gitter

@trotyl
Copy link
Contributor

trotyl commented Feb 9, 2018

Duplicate of #6618 (woking as intended for bug report, not implementable for feature request), possibly could improve the docs.

@junghoocho
Copy link
Author

junghoocho commented Feb 10, 2018

@trotyl Thanks for the pointer! I understand why Angular maintainers may not want to change the current behavior given its potentially negative performance implication.

But the current behavior of a template reference variable puts more strain on the developer's mind; it is one more exception that we need to remember and pay attention to. The current wording in the documentation (https://angular.io/guide/architecture) is clear and intuitive. "Angular processes all data bindings once per JavaScript event cycle", but the real behavior is, roughly, "All data binding is processed once per event cycle, unless the data binding contains only a template reference variable
whose element's events are not bound" (b.t.w. what about template input variable? Does it get processed in each event cycle? Is there difference in behavior depending on whether it comes from a template reference variable or a component property?).

If the change of the current behavior leads to unbearably high overhead, there might be not much that the maintainers or users can do. We just have to take whatever is practically possible. But I hope that both sides of this option is carefully weighed by the community: the elegance and simplicity of the template syntax vs high-performance low-overhead implementation.

@junghoocho
Copy link
Author

junghoocho commented Feb 10, 2018

@Toxicable Here it is:

https://stackblitz.com/edit/angular-gitter-eafvrz?file=app%2Fapp.component.html

The behavior of the first input box (which binds to the input event) is what I expected. The behavior of the second input box (with no input event binding) is rather unpredictable; the submit button stays disabled most of the time, but it gets enabled sometimes when I type something into the first input box.

@trotyl
Copy link
Contributor

trotyl commented Feb 10, 2018

Angular processes all data bindings once per JavaScript event cycle

If no event listener defined, there won't be an event cycle (tick) in the JavaScript VM, it's technically true.

@Toxicable
Copy link

I've formatted it a bit to make it easier to explain https://stackblitz.com/edit/angular-gitter-myueqn?file=app/app.component.ts
The explanation for your behavior is that when you're typing into the second Angular is not running Change Detection (CD) (The process of updating Angular's bindings) becasue there is nothing bound to the input event. Wgile the value does get updated it's simply not reflected by the UI since CD has not been ruin.
The first input however does have a bound event (input)="0", therefore CD is run everytime that event is fired.
You can confirm this by doing the ofllowing

  • type: 123 into Input2
  • type: 1 into input1
    You'll notice the bindings for Angular's values only updates once your type into input1

I believe this is the intended behavior of such a case.
Either way i'd recommend using Angular Forms to handle inputs anyway
https://angular.io/guide/user-input
https://angular.io/guide/forms
https://angular.io/guide/reactive-forms

@mhevery
Copy link
Contributor

mhevery commented Feb 13, 2018

Hello, we reviewed this issue and determined that it doesn't fall into the bug report or feature request category. This issue tracker is not suitable for support requests, please repost your issue on StackOverflow using tag angular.

If you are wondering why we don't resolve support issues via the issue tracker, please check out this explanation.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants