Knockout.js ko.mapping.toJS, на мой взгляд, не обновляет данные

Я беру объект json с сервера и заполняю свое представление. Затем я изменяю данные и отправляю их обратно на сервер. Затем я получаю новую копию данных, надеясь, что она обновит мое представление с любыми изменениями. Однако этого не происходит. TIA

$(document).ready(function() {
    var customer_id = get_customer_id();
    var data = load_model();
    contract_model = ko.mapping.fromJS(data,{});
    ko.applyBindings(contract_model);
}

function load_model(){
    var url = '/ar/contract_json?contract_id='+get_contract_id();
    var data = '';
    $.ajax({
        type:'GET',
        url:url,
        async:false,
        success: function(returningValue){
            data = returningValue;
        }
    });
    return data;
}

Эта начальная загрузка работает нормально. Затем я делаю кое-что, меняю одну из наблюдаемых и отправляю эти данные обратно на сервер. Сервер получает обновление, а затем я делаю новую выборку данных, чтобы это представление обновилось (я знаю, что могу передать новые данные за один шаг, но это в коде, который я еще не реорганизовал).

function refresh_data(contract_model){
    var url = '/ar/contract_json?contract_id='+get_contract_id();
    $.post(url,function(data){
        console.log(data);
        ko.mapping.fromJS(contract_model,{},data);
        ko.applyBindings(contract_model);
        console.log(ko.mapping.toJS(contract_model))
    });

}

function refresh_data(contract_model){
    var url = '/ar/contract_json?contract_id='+get_contract_id();
    $.post(url,function(data){
        console.log(data);
        ko.mapping.fromJS(contract_model,{},data);
        console.log(ko.mapping.toJS(contract_model))
    });

}

function push_model(contract_model,refresh){
    var url = '/ar/update_contract';
    var data = {'contract':ko.mapping.toJSON(contract_model)}

    delete data['lines'];
    $.post(url,data,function(return_value){
        if (refresh){
            refresh_data(contract_model);
        };
    });
}

Все сообщения консоли показывают, что новые данные возвращаются, но мое представление никогда не обновляется.


person Ominus    schedule 16.02.2012    source источник


Ответы (3)


Я считаю, что проблема связана с порядком параметров, которые вы передаете в функцию ko.mapping.fromJS при обновлении contract_model.

У вас есть:

ko.mapping.fromJS(contract_model,{},data);

ты хочешь:

ko.mapping.fromJS(data, {}, contract_model);
person seth.miller    schedule 16.02.2012
comment
Документы KnockOut для плагина Mapping, IMO, неверны по синтаксису для вызова ko.mapping.fromJS (...). Документы показывают следующее: ko.mapping.fromJS (data, viewModel), но явно это должно быть: ko.mapping.fromJS (data, {}, viewModel) - person Armchair Bronco; 10.07.2012
comment
Потратил на это часы. Спасибо, это было большим подспорьем. - person Geoff Wells; 21.05.2014
comment
Я тоже потратил на это часы. Я должен тебе шесть пачек - person stackoverfloweth; 23.11.2016

Ответ @seth.miller правильный. Вы также можете не указывать средний параметр "options", если ваш contract_model тот же, который был отображен ранее. Если есть только два аргумента, ko.mapping.fromJS проверяет, имеет ли второй аргумент свойство "__ko_mapping__". Если это так, он рассматривает его как цель, в противном случае он рассматривает его как объект параметров.

person DBueno    schedule 11.12.2012
comment
Тьфу, это тупо. Если второй аргумент не имеет свойства "__ko_mapping__", а третий аргумент не существует, тогда он действительно должен рассматривать второй аргумент как цель. - person Simon_Weaver; 13.05.2015

Основываясь на наблюдении @DBueno - всем, кто использует машинописный текст, я настоятельно рекомендую закомментировать эту сигнатуру метода из вашего knockout.mapping.d.ts файла.

// fromJS(jsObject: any, targetOrOptions: any): any;

Да - просто прокомментируйте.

введите описание изображения здесь

Затем вы получите ошибку времени компиляции, если попытаетесь сделать:

ko.mapping.fromJS(item.data, item.target);

и вы можете заменить его на более безопасный

ko.mapping.fromJS(item.data, {}, item.target);

Безопаснее, потому что независимо от того, был ли item.target ранее сопоставлен (и, следовательно, имел бы свойство __ko_mapping__), он всегда будет копировать свойства.

person Simon_Weaver    schedule 13.05.2015