Knockoutjs可观察和jQuery扩展功能

时间:2013-12-05 08:29:22

标签: javascript jquery knockout.js

假设我有以下代码:

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调用不是异步的。

1 个答案:

答案 0 :(得分:0)

第一个问题是你正在扩展self,这是一个范围变量,只存在于Klass函数中,而不是你通过调用它创建的实例。

如果您在调用$.extend(this, data);时需要覆盖value,则需要致电update。 虽然我明白为什么你在那里使用self。 但是,通过调用observable添加的ko.mapping.fromJS功能将丢失。 value不再是函数(ko observable),而是标量值(234)。您必须再次调用obj = ko.mapping.fromJS(obj);以将值包装为observable

第二个问题是$.getasynchronous所以在调用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());
});