Reputation: 770
I wrote a quick and dirty list ui in js and html that can be filtered: https://jsfiddle.net/maxbit89/2jab4fa4/
So the usage of this looks like this (Fiddle line: 96):
var list = new ui_list(document.body, 200, 300, "Test");
var encoder = function(dom, value) {
console.log("begin encoding");
console.log(value)
dom.innerHTML = value.n;
}
list.add({'n': 1}, function() {
this.value.n++;
console.log(this.value.n);
// this.value = this.value;
}, encoder);
So what this basically does is create a List and adds a Element to it that has an Object: {'n': 1} as a value and a onClickHandler(second parameter on list.add) which should increase the value by 1 (fiddle line: 104)
But it won't do this until you uncomment the line 106 in the fiddle. (Tested with Firefox 50.1.0, and Edge Browser)
Has any body an idea why js behaves like this? In a much simpler example this works just fine:
var myObj= {
'onvalueChange' : function() {
console.log('value changed');
},
'print' : function() {
console.log('value:');
console.log(this.value);
console.log(this.value.n);
}
};
Object.defineProperty(myObj, "value", {
get: function() { return this._value; },
set: function(value) {
this.onvalueChange();
this._value = value;
}
});
myObj.value = {'n' : 1};
myObj.value.n++;
myObj.print();
Upvotes: 2
Views: 80
Reputation: 31692
First you have the setter defined like this:
set: function (value) {
this.encoder(this, value);
this._value = value;
}
that means that every time the value is set, the encoder will be called with the new value to update the equivalent DOM element.
But then inside the event listener function you have:
function() {
this.value.n++;
console.log(this.value.n);
//this.value = this.value;
}
where you think that this.value.n++
is setting the value (means it calls the setter which means the encoder will be called to update the DOM element). But it's not true. this.value.n++
is actually calling the getter. To explain more this:
this.value.n++;
is the same as:
var t = this.value; // call the getter
t.n++; // neither call the getter nor the setter. It just uses the reference (to the object) returned by the getter to set n
So, when you uncomment the line this.value = this.value;
, the setter gets called, and the encoder gets called to update the DOM element.
So to fix the issue you have to either:
this.value.n++;
to actually call the setter like: this.value = {n: this.value.n + 1};
(but this is hacky too as if value has a lot of key-value pairs then you have to enlist them all here just to set n
).this.callEncoder()
) that will call it and [you] call the new function instead inside the event listener).Upvotes: 3