-
Notifications
You must be signed in to change notification settings - Fork 27.4k
feat($rootScope): Add custom compare and copy functions to $watch #10096
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -353,11 +353,13 @@ function $RootScopeProvider() { | |
* - `newVal` contains the current value of the `watchExpression` | ||
* - `oldVal` contains the previous value of the `watchExpression` | ||
* - `scope` refers to the current scope | ||
* @param {boolean=} objectEquality Compare for object equality using {@link angular.equals} instead of | ||
* comparing for reference equality. | ||
* @param {boolean=|function()} objectEquality Compare for object equality using {@link angular.equals} instead of | ||
* comparing for reference equality. If a function is passed, it will be used as a replacement for {@link angular.equals}. | ||
* @param {function()} copier Replacement function for {@link angular.copy} to save value into oldVal for next | ||
change event. | ||
* @returns {function()} Returns a deregistration function for this listener. | ||
*/ | ||
$watch: function(watchExp, listener, objectEquality) { | ||
$watch: function(watchExp, listener, objectEquality, copier) { | ||
var get = $parse(watchExp); | ||
|
||
if (get.$$watchDelegate) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need an extra test for expressions that generate a watchDelegate? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh I forgot about this bit. There is a quite a bit of work to do here as each of the delegates in the parser need to be updated. We definitely need to test this. |
||
|
@@ -370,7 +372,9 @@ function $RootScopeProvider() { | |
last: initWatchVal, | ||
get: get, | ||
exp: watchExp, | ||
eq: !!objectEquality | ||
eq: !!objectEquality, | ||
equals: isFunction(objectEquality) ? objectEquality : equals, | ||
copy: isFunction(copier) ? copier : copy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we decide to move forward, then this looks like the wrong approach. We should not add new properties, and change #10096 (comment) can be used as a template, but in this specific case it can be simplified by using the If implemented that way, then there is no need to change any of the delegates |
||
}; | ||
|
||
lastDirtyWatch = null; | ||
|
@@ -763,12 +767,12 @@ function $RootScopeProvider() { | |
if (watch) { | ||
if ((value = watch.get(current)) !== (last = watch.last) && | ||
!(watch.eq | ||
? equals(value, last) | ||
? watch.equals(value, last) | ||
: (typeof value === 'number' && typeof last === 'number' | ||
&& isNaN(value) && isNaN(last)))) { | ||
dirty = true; | ||
lastDirtyWatch = watch; | ||
watch.last = watch.eq ? copy(value, null) : value; | ||
watch.last = watch.eq ? watch.copy(value, null) : value; | ||
watch.fn(value, ((last === initWatchVal) ? value : last), current); | ||
if (ttl < 5) { | ||
logIdx = 4 - ttl; | ||
|
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.
We should have a check:
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.
Why is that ? What is wrong with using default
copy()
with a customobjectEquality()
?I will usually not make sense, but why should it be our concern ? 😁
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.
To make it clear that if you are going to mess with the way equality works you also have to understand that copy will likely need to change too
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.
Aha, makes sense !
Or we can force them tick a checkbox that says "I have read and understood the implications" 😁
It would be useful to add more docs about it and how to use the feature properly (maybe an example too). I guess something tbd before merging.
I generally like the idea.
Any benchpress experts around ? Would be useful to make sure that performance isn't affected when you don't use tge feature (e.g. core stuff) and that it gets improved (when used correctly) for user stuff.