Knockoutjs observable and jQuery extends function

2019-07-20 09:16发布

Let's say I have the following code:

var Klass = function(){
  var self = this;
  this.value = 123;

  this.update = function(){
    $.ajax({
      url: '/whatever', 
      async: false,
      success: function(data){
        $.extend(self, data);
      }
    });
  }
}

Lets assume, '/whatever' returns this json object:

{value: 234}

And when I do this:

var obj = new Klass();
obj = ko.mapping.fromJS(obj);
console.log(obj);

We all know obj is now an knockoutjs observable.

And I run this:

obj.update();
console.log(obj);

What I have discovered is, value of obj doesn't get overridden as a simple value 234, but stayed as an observable property.

My questions are:

1) why is this?

2) How do I make the update work as I wanted.

UPDATE: ajax call is not asynchronous.

1条回答
手持菜刀,她持情操
2楼-- · 2019-07-20 09:43

First issue is that you are extending self, which is a scoped variable and only exists inside the Klass function, not it's instances you create by calling it.

You'll need to call $.extend(this, data); if you need to overwrite value when calling update. Although I do understand why you are using self there. But the observable functionality added by calling ko.mapping.fromJS is then lost. value is no longer a function (ko observable) but a scalar value (234). You have to call obj = ko.mapping.fromJS(obj); again to wrap value as observable.

Second issue is that $.get is asynchronous so calling console.log(obj) right after calling obj.update will log the value before the GET response comes. You need to wait for it to execute (use a callback).

Here's a working 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());
});
查看更多
登录 后发表回答