使用ko.mapping.fromJS在异步ajax调用之后更新knockout observable

时间:2014-12-29 23:40:17

标签: javascript ajax json knockout.js knockout-mapping-plugin

我有一个简单的用例。我需要异步调用WS并在UI上显示返回的JSON。我得到的JSON是一个具有多个属性的对象。为简单起见,下面的代码只有一个属性。由于我有多个属性,我使用ko.mapping.fromJS将JSON映射到对象属性。这一切似乎都有效,除了获取的数据不会在UI上更新。如果我手动更新observable,它可以工作。但不是在使用ko.mapping.fromJS时。

的Javascript

function AppViewModel() {
var self = this;
self.firstName = ko.observable("Bert");

$.ajax({
    dataType: 'json',
    async: true,
    type: 'POST',
    url: '/echo/json/',
    data: {
        json: '{"firstName":"Bob1"}'
    }
}).done(function(data) {
    console.log(data);

    //self.firstName(data.firstName);//This works
    self = ko.mapping.fromJS(data); //This doesn't

    console.log(self.firstName());
}).fail(function(jqxhr, textStatus, error) {
    alert('there was an error');
});
}

// Activates knockout.js
var avm = new AppViewModel();
ko.applyBindings(avm);

HTML

<p>First name: <strong data-bind="text: firstName"></strong></p>

你可以运行jsfiddle。你会看到这条线路正常工作

self.firstName(data.firstName);//This works

并且此行不起作用

self = ko.mapping.fromJS(data); //This doesn't

http://jsfiddle.net/texag93/fakdf5Lw/53/

1 个答案:

答案 0 :(得分:1)

两件事:1)您需要使用ko.mapping.fromJS创建初始视图模型,2)您需要在更新时将现有视图模型作为第二个参数传递给fromJS

所以这样的话:

// Activates knockout.js
var avm = ko.mapping.fromJS({firstName: 'Bert'});
ko.applyBindings(avm);

$.ajax({
    dataType: 'json',
    async: true,
    type: 'POST',
    url: '/echo/json/',
    data: {
        json: '{"firstName":"Bob1"}'
    }
}).done(function(data) {
    console.log(data);

    ko.mapping.fromJS(data, avm);

    console.log(avm.firstName());
}).fail(function(jqxhr, textStatus, error) {
    alert('there was an error');
});

更新了小提琴:http://jsfiddle.net/fakdf5Lw/56/