Skip to content

Watcher false triggering #1014

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

Closed
miljan-aleksic opened this issue Jul 6, 2015 · 8 comments
Closed

Watcher false triggering #1014

miljan-aleksic opened this issue Jul 6, 2015 · 8 comments

Comments

@miljan-aleksic
Copy link

Here I am again, reporting another bug :)

When $watch is set on some deeper level and the root is altered the callback is triggered. This happens only when deep is On and the some new value is being added.

It's difficult to explain, so please check the fiddle. There the $watch should not be triggered as 'some' value is not changed, but it does. Same happens using this.$watch.

@azamat-sharapov
Copy link

I think $add is changing whole $data object, so watcher catches changes on deep: true. Because if you init property in you $data (which is recommended), it won't happen, but yeah, sometimes we need to $add on the fly.

@miljan-aleksic
Copy link
Author

Yes, sometimes when you are adding dynamic components that rely on the same main object. I can say that this behaviour is new introduced after 0.12 and changelog have no reference to it, so I assume is a bug.

@yyx990803
Copy link
Member

It's actually not new. $adding a root-level property always trigger a full digest for all watchers. This is because if a watcher is watching a non-existent property, it would have caught no dependencies on initialization, and there's no way to notify it unless we do a full digest. This is also why I strongly recommend against $adding root level properties on the fly.

@azamat-sharapov
Copy link

This is useful info, Evan, didn't know about this. Should probably be added somewhere in docs..

@miljan-aleksic
Copy link
Author

Thanks for looking into this Evan, maybe I'm getting confused but I'm not watching a non-existing property. Eg {someData: {my-value: 89}}

I start watching changes for 'my-value', with $.watch('data.my-value', {}, deep: true). Then I add another root level value with $add('someData', {}) and the object become {someData: {my-value: 89}, moreData{}}. I would expect my watch be exclusively triggered if some of the 'my-value' data is changed. But seems I'm wrong?

@yyx990803
Copy link
Member

Yeah, adding a root level property triggers a re-evaluation of all watchers in that component. For normal watchers, if the previous value and the new value didn't change, the callback is not triggered; but deep watchers would trigger even if the value was the same (because it could be the same object but mutated). Maybe in this case the digest could be "shallow", i.e. only calls the callback when the value has changed.

@miljan-aleksic
Copy link
Author

The "shallow" option sounds good, because for deeper level watchers it doesn't matter if the object has mutated or not, the only what matter if the watched value has changed. I don't mind if its a default behaviour or optional, but I would keep it always On in my code :)

@miljan-aleksic
Copy link
Author

Thanks Evan :)

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

No branches or pull requests

3 participants