Knockout.js ko.mapping.toJS 在我看来没有刷新数据

Posted

技术标签:

【中文标题】Knockout.js ko.mapping.toJS 在我看来没有刷新数据【英文标题】:Knockout.js ko.mapping.toJS not refreshing data in my view 【发布时间】:2012-03-07 11:03:24 【问题描述】:

我从服务器获取一个 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);
        ;
    );

控制台消息都显示返回的新数据,但我的视图从未更新。

【问题讨论】:

【参考方案1】:

我认为问题在于您在更新contract_model 时传递给ko.mapping.fromJS 函数的参数顺序。

你有:

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

你想要的:

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

【讨论】:

映射插件的 KnockOut 文档在 IMO 调用 ko.mapping.fromJS(...) 的语法上是错误的。文档显示以下内容:ko.mapping.fromJS(data, viewModel),但显然应该是:ko.mapping.fromJS(data, , viewModel) 在这上面花了几个小时。谢谢你,这是一个很大的帮助。 我也花了几个小时在这上面。我欠你六块腹肌【参考方案2】:

@seth.miller 的回答是正确的。如果您的contract_model 与之前映射的相同,您也可以省略中间的“选项”参数。如果只有两个参数,ko.mapping.fromJS 检查第二个参数是否具有"__ko_mapping__" 属性。如果是,则将其视为目标,否则将其视为选项对象。

【讨论】:

呃,这太愚蠢了。如果第二个参数没有"__ko_mapping__" 属性并且第三个参数不存在,那么它确实应该将第二个参数视为目标。【参考方案3】:

根据@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__ 属性),它始终会复制属性。

【讨论】:

以上是关于Knockout.js ko.mapping.toJS 在我看来没有刷新数据的主要内容,如果未能解决你的问题,请参考以下文章

带有 knockout.js 和 ORM 的 TypeScript

更新 knockout.js 和 SignalR 库后,knockout-mapping js 不会更新视图中的列表

knockout.js - 数据绑定文本默认值

knockout.js

knockout.js

Knockout.js 和 Jquery Mobile