Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Knockout.js's default equality comparer treat non-primitive types as not equal?

Tags:

knockout.js

From the Knockout v2.1.0 debug source code:

ko.observable['fn'] = {
    "equalityComparer": function valuesArePrimitiveAndEqual(a, b) {
        var oldValueIsPrimitive = (a === null) || (typeof(a) in primitiveTypes);
        return oldValueIsPrimitive ? (a === b) : false;
    }
};

This seems unintuitive to me but there must be some reason Steve Sanderson went out of his way to define this. Why would this be the case? It seems to unnecessarily trigger change notifications.

like image 444
Davy8 Avatar asked Oct 03 '12 18:10

Davy8


2 Answers

This was done because if you have an observable that holds an object, Knockout does not know if sub-properties were changed or not.

At this point, we trigger a notification just in case one of the object's properties did change.

like image 109
RP Niemeyer Avatar answered Nov 12 '22 09:11

RP Niemeyer


If you have an observable, which is holding an object, you could make a custom equalityComparer, to return equality based on your needs. Just set the property on the observable instance you want to customize. The signature is:

myObservable["equalityComparer"] = function(a, b){ 
  return a===b;// Or any arbitrary comparison
};

Now your observable is only raising change-event, when function is returning false.

like image 25
Jesper Jensen Avatar answered Nov 12 '22 10:11

Jesper Jensen