Closed fastfasterfastest closed 9 years ago
This isn't documented, but you can change how an observable determines whether values are equal by setting the equalityComparer
method of the observable:
myObservable.equalityComparer = function(a, b) {
if (a instanceof Date && b instanceof Date) {
return a.toDateString() == b.toDateString();
} else {
return ko.observable.fn.equalityComparer(a, b);
}
};
If you want to affect all observables or computed observables, you can modify ko.observable.fn.equalityComparer
or ko.computed.fn.equalityComparer
directly.
Thanks. Interestingly, the observable I use to compute the value to return in the pureComputed was already using such an equalityComparer. That observable holds a Date object and I install an equalityComparer on it for that very purpose. I did that a quite some time ago and had forgotten about it. In this case, I also need to install such an equalityComparer on the pureComputed. Thanks for suggesting that!
Nevertheless, I think it might be a good idea if knockout (out of the box) considered two intrinsic Date object equal if they both have the same value.
By the way, I used a.valueOf() === b.valueOf(), instead of a.toDateString() == b.toDateString(), as a micro-optimization.
I'm glad you've got it working.
I have a pureComputed that returns a javascript Date object. I register a subscription to the pureComputed's changes using .subscribe. However, the subscription is triggered even when the same value is returned by the pureComputed.
The reason is explained at http://knockoutjs.com/documentation/computedObservables.html which states:
My pureComputed does not hold a "primitive value", but instead a javascript Date object. Would it be reasonable to request knockout to handle a javascript Date object the same way as it currently handles "primitive values" (perhaps by using .valueOf())?