Hy我用js和html编写了一个快速而又脏的列表ui,可以过滤: https://jsfiddle.net/maxbit89/2jab4fa4/
所以这个的使用看起来像这样(小提琴行: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);
所以这个基本的做法是创建一个List并为其添加一个Element,它有一个Object:{' n':1}作为值和onClickHandler(list.add上的第二个参数)应该将值增加1(小提琴线:104)
但它不会这样做,直到你取消小提琴中的106行。 (使用FireFox 50.1.0和Edge Browser进行测试)
有没有人知道为什么js会像这样? 在一个更简单的例子中,这很好用:
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();
答案 0 :(得分:3)
首先你有这样定义的setter:
set: function (value) {
this.encoder(this, value);
this._value = value;
}
这意味着每次设置值时,都会使用新值调用编码器来更新等效的DOM元素。
但是在事件监听器功能中你有:
function() {
this.value.n++;
console.log(this.value.n);
//this.value = this.value;
}
您认为this.value.n++
正在设置值(意味着它调用setter,这意味着将调用编码器来更新DOM元素)。但事实并非如此。 this.value.n++
实际上是在调用getter。要解释更多:
this.value.n++;
与:
相同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
因此,当您取消注释行this.value = this.value;
时,将调用setter,并调用编码器来更新DOM元素。
所以要解决你必须要解决的问题:
this.value.n++;
以实际调用setter,如:this.value = {n: this.value.n + 1};
(但这也很hacky,因为值有很多键值对,那么你必须将它们全部放在这里才能设置n
)。this.callEncoder()
)它和[你]在事件监听器内调用新函数。)。