2013-12-05 4 views
2

Скажем, у меня есть следующий код:Knockoutjs наблюдаемым и JQuery расширяет функции

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

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

Давайте предположим, '/ все' возвращает этот 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) Как сделать обновление, как я хотел.

UPDATE: вызов ajax не является асинхронным.

ответ

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()); 
}); 
+0

Да, я буду называть отображение снова после –

+0

В таком случае. См. Мой обновленный ответ. –

+0

Привет, что касается обратного вызова, на самом деле я использую asycn: false, я просто набрал этот код намного проще здесь перед сном. Но спасибо за это. –

Смежные вопросы