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

Commit 81b1cc4

Browse files
committed
feat($rootScope): Add custom equals and copy functions to $watch
Closes #10069
1 parent a9352c1 commit 81b1cc4

File tree

2 files changed

+65
-6
lines changed

2 files changed

+65
-6
lines changed

src/ng/rootScope.js

+10-6
Original file line numberDiff line numberDiff line change
@@ -353,11 +353,13 @@ function $RootScopeProvider() {
353353
* - `newVal` contains the current value of the `watchExpression`
354354
* - `oldVal` contains the previous value of the `watchExpression`
355355
* - `scope` refers to the current scope
356-
* @param {boolean=} objectEquality Compare for object equality using {@link angular.equals} instead of
357-
* comparing for reference equality.
356+
* @param {boolean=|function()} objectEquality Compare for object equality using {@link angular.equals} instead of
357+
* comparing for reference equality. If a function is passed, it will be used as a replacement for {@link angular.equals}.
358+
* @param {function()} copier Replacement function for {@link angular.copy} to save value into oldVal for next
359+
change event.
358360
* @returns {function()} Returns a deregistration function for this listener.
359361
*/
360-
$watch: function(watchExp, listener, objectEquality) {
362+
$watch: function(watchExp, listener, objectEquality, copier) {
361363
var get = $parse(watchExp);
362364

363365
if (get.$$watchDelegate) {
@@ -370,7 +372,9 @@ function $RootScopeProvider() {
370372
last: initWatchVal,
371373
get: get,
372374
exp: watchExp,
373-
eq: !!objectEquality
375+
eq: !!objectEquality,
376+
equals: isFunction(objectEquality) ? objectEquality : equals,
377+
copy: isFunction(copier) ? copier : copy
374378
};
375379

376380
lastDirtyWatch = null;
@@ -763,12 +767,12 @@ function $RootScopeProvider() {
763767
if (watch) {
764768
if ((value = watch.get(current)) !== (last = watch.last) &&
765769
!(watch.eq
766-
? equals(value, last)
770+
? watch.equals(value, last)
767771
: (typeof value === 'number' && typeof last === 'number'
768772
&& isNaN(value) && isNaN(last)))) {
769773
dirty = true;
770774
lastDirtyWatch = watch;
771-
watch.last = watch.eq ? copy(value, null) : value;
775+
watch.last = watch.eq ? watch.copy(value, null) : value;
772776
watch.fn(value, ((last === initWatchVal) ? value : last), current);
773777
if (ttl < 5) {
774778
logIdx = 4 - ttl;

test/ng/rootScopeSpec.js

+55
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,61 @@ describe('Scope', function() {
458458
expect(log).toEqual([]);
459459
}));
460460

461+
it('should use custom equals and copy functions',
462+
inject(function($rootScope) {
463+
var log = [];
464+
var oldLog = [];
465+
466+
function logger(newVal, oldVal) {
467+
log.push(newVal);
468+
oldLog.push(oldVal);
469+
}
470+
471+
var watched = "ABC";
472+
var watchedFn = function() {
473+
return watched;
474+
};
475+
476+
// Comparator returns true if string starts with same character
477+
var comparator = function(newVal, oldVal) {
478+
if (oldVal === newVal) return true;
479+
if (oldVal === undefined || newVal === undefined) return false;
480+
if (newVal.length === oldVal.length === 0) return true;
481+
if (newVal.length > 0 && oldVal.length > 0 && oldVal[0] === newVal[0]) {
482+
return true;
483+
}
484+
return false;
485+
};
486+
487+
// Copier add " copy" to value
488+
var copier = function(value) {
489+
if (value !== undefined) {
490+
return value + " copy";
491+
}
492+
return undefined;
493+
};
494+
495+
$rootScope.$watch(watchedFn, logger, comparator, copier);
496+
497+
$rootScope.$digest();
498+
expect(log).toEqual(['ABC']);
499+
expect(oldLog).toEqual(['ABC']);
500+
log = [];
501+
oldLog = [];
502+
503+
watched = "DEF";
504+
$rootScope.$digest();
505+
expect(log).toEqual(['DEF']);
506+
expect(oldLog).toEqual(['ABC copy']);
507+
log = [];
508+
oldLog = [];
509+
510+
watched = "DZZ";
511+
$rootScope.$digest();
512+
expect(log).toEqual([]);
513+
expect(oldLog).toEqual([]);
514+
}));
515+
461516

462517
describe('$watch deregistration', function() {
463518

0 commit comments

Comments
 (0)