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

preventDefault preventing ng-checked and ng-model bindings from working #15285

Closed
amaschas opened this issue Oct 17, 2016 · 10 comments
Closed

preventDefault preventing ng-checked and ng-model bindings from working #15285

amaschas opened this issue Oct 17, 2016 · 10 comments

Comments

@amaschas
Copy link

Using preventDefault on an ng-click callback sends the state of a checkbox out of sync with ng-model and ng-checked bindings. Example here:

http://plnkr.co/edit/419QQthL8MmP2fQzVBog

Not quite sure why this happens, but the desired behavior is that the checkbox is checked when the bound value is true. There are a few use cases for this, for instance if you want to display modal warning before letting a user check a checkbox, or if you want another component to handle the model update that sets the checkbox state to checked.

@Narretz
Copy link
Contributor

Narretz commented Oct 17, 2016

Angular needs the DOM events to do the bindings. When you prevent the click, Angular cannot set the checked. And why would it? You just prevented the click, the checkbox is not checked.

This is expected behavior. When the user interacts with DOM elements, Angular tries to respect the regular rules of the DOM.

@amaschas
Copy link
Author

I guess I'm a little confused as to what's happening here. It seems like a digest cycle still happens even after the preventDefault, so I would think that because I'm updating a scope variable, that the DOM would update to represent the bound state. The click event and the application of the checked attribute to the element seem like two totally different things, which just happen to be related in the default case. My sense was that the preventDefault would stop the default behavior of the checkbox being applied, but a digest cycle would run, and the ng-checked directive would then apply the checked attribute.

@Narretz
Copy link
Contributor

Narretz commented Oct 17, 2016

You have two different variables in your code: isChecked, isClicked. Is that the cause of your confusion?

@amaschas
Copy link
Author

Sorry, forgot to save my local changes to the plunker, should be using the correct variable name now,

@Narretz
Copy link
Contributor

Narretz commented Oct 17, 2016

Looks the same too me. Here's an update: http://plnkr.co/edit/KOQo6ztxV1QTw5VfvjCA?p=preview

@amaschas
Copy link
Author

Eh, not sure why the plunker isn't updating, but you can see the behavior I'm describing.

@Narretz
Copy link
Contributor

Narretz commented Oct 18, 2016

The plnkr still doesn't do what I think you want - setting isChecked in the click handler instead of isClicked. Maybe you didn't save your plnkr or forked it before?

But even if it does, the checkbox will not appear "checked", even if isChecked is set after preventDefault. I assume this is because the browser prevents the checking with preventDefault, and the subsequent change to the checked attribute comes too fast. Wrapping it in a timeout works: http://plnkr.co/edit/yVPKBCfXhgbhzurcqVxd?p=preview

@Narretz
Copy link
Contributor

Narretz commented Nov 3, 2016

Due to lack of feedback, I'm going to close this as working as expected based on my explanation above

@houyhea
Copy link

houyhea commented Aug 1, 2017

I meet the same question.
Checkbox use ng-model.Then add click eventHandle using a customDirective .In the eventHandle function,exeute e.preventDefault(). as a result,ng-model change to true,I thought it would not be change.
-----coming from google search. AngularJS v1.2.28

@johnaddme
Copy link

o

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants