假设我有以下代码:
var Klass = function(){
var self = this;
this.value = 123;
this.update = function(){
$.ajax({
url: '/whatever',
async: false,
success: function(data){
$.extend(self, data);
}
});
}
}
让我们假设,'/ whatever'返回这个json对象:
{value: 234}
当我这样做时:
var obj = new Klass();
obj = ko.mapping.fromJS(obj);
console.log(obj);
我们都知道obj
现在是一个可以观察到的敲门声。
我跑了这个:
obj.update();
console.log(obj);
我发现的是,obj
的值不会被覆盖为一个简单的值234,而是作为一个可观察的属性保留。
我的问题是:
1)为什么会这样?
2)如何使更新正常工作。
更新:ajax调用不是异步的。
答案 0 :(得分:0)
第一个问题是你正在扩展self
,这是一个范围变量,只存在于Klass函数中,而不是你通过调用它创建的实例。
如果您在调用$.extend(this, data);
时需要覆盖value
,则需要致电update
。
虽然我明白为什么你在那里使用self
。
但是,通过调用observable
添加的ko.mapping.fromJS
功能将丢失。 value
不再是函数(ko observable
),而是标量值(234
)。您必须再次调用obj = ko.mapping.fromJS(obj);
以将值包装为observable
。
第二个问题是$.get
是asynchronous所以在调用console.log(obj)
之后立即调用obj.update
将在GET响应到来之前记录该值。您需要等待它执行(使用回调)。
这是一个有效的fiddle。
var Klass = function(){
this.value = 123;
this.update = function(callback){
var self = this;
$.get('/', function(data) {
$.extend(self, {value: 234});
callback.call(undefined);
});
}
}
var obj = new Klass();
obj = ko.mapping.fromJS(obj);
console.log(obj.value());
obj.update(function() {
obj = ko.mapping.fromJS(obj);
console.log(obj.value());
});