假设我有以下代码:
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
现在是一个 knockoutjs observable。
然后我运行这个:
obj.update();
console.log(obj);
我发现的是,obj
的值不会被覆盖为简单值 234,而是保留为可观察属性。
我的问题是:
1)这是为什么?
2) 如何让更新按我想要的方式工作。
更新:ajax 调用不是异步的。
最佳答案
第一个问题是您正在扩展 self
,它是一个作用域变量,只存在于 Klass 函数内部,而不是您通过调用它创建的实例。
如果在调用 update
时需要覆盖 value
,则需要调用 $.extend(this, data);
。
尽管我确实理解您为什么要在那里使用 self
。
但是通过调用 ko.mapping.fromJS
添加的 observable
功能会丢失。 value
不再是一个函数 (ko observable
),而是一个标量值 (234
)。您必须再次调用 obj = ko.mapping.fromJS(obj);
将值包装为 observable
。
第二个问题是 $.get
是 asynchronous因此在调用 obj.update
之后调用 console.log(obj)
将在 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());
});
关于javascript - Knockoutjs observable 和 jQuery extends 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20394977/