使用KnockoutJS映射插件执行部分更新

fal*_*loi 6 knockout-mapping-plugin knockout.js

现在,我正在使用这个JSON与KO Mapping插件,它工作正常:

{
  "Controls": [
    {
      "Fields": [
        {
          "Name": "emailField", 
          "Text": "email", 
          "Visible": true
        }, 
        {
          "Name": "hiddenField", 
          "Text": "text", 
          "Visible": true
        }
      ], 
      "Name": "form2", 
      "Type": "Form"
    }, 
    {
      "Data": [
        [
          "Federico Aloi", 
          20
        ], 
        [
          "Andres Lopez", 
          31
        ], 
        [
          "Pablo Perez", 
          32
        ]
      ], 
      "Fields": [
        {
          "Name": "nameField", 
          "Text": "Nombre", 
          "Visible": true
        }, 
        {
          "Name": "ageField", 
          "Text": "Edad", 
          "Visible": true
        }
      ], 
      "Name": "datagrid1", 
      "Type": "Datagrid"
    }
  ], 
  "Name": "pagina1", 
  "Title": "Probando el KO"
}
Run Code Online (Sandbox Code Playgroud)

现在我的要求是执行"部分更新".有些情况我想这样做:

  • 我需要在第二个控件中更改数据数组.
  • 我只需要更新一个Control而不是整个页面(这是我正在序列化的类,这个JSON中的根).
  • 我需要为我的页面添加另一个控件.

也许另一种解决方法是重新创建原始对象ko.mapping.toJS(viewModel),更改它然后再重新映射...但我相信你会得到更好的东西.


编辑:我试过ko.mapping.fromJS(updatedControl, viewModel.Controls()[0])但它没有用,这是我的代码:

function (control) {
    $.getJSON($.format('api/control/{0}/{1}', viewModel.Name(), control.Name()), function (response) {
        ko.mapping.fromJS(response, viewModel.Controls()[0]);
    });
},
Run Code Online (Sandbox Code Playgroud)

响应:

{
  "Fields": [
    {
      "Name": "emailField", 
      "Text": "email", 
      "Visible": true
    }, 
    {
      "Name": "hiddenField", 
      "Text": "text", 
      "Visible": true
    }
  ], 
  "Name": "form2", 
  "Type": "Form"
}
Run Code Online (Sandbox Code Playgroud)

EDIT2:http://jsfiddle.net/faloi/4FcAy/10/上查看

mad*_*kay 6

我认为这是映射插件中最受欢迎的问题.该插件目前只能对属性进行部分更新.例如,如果您要将以下数据重新映射到您的对象

{ "Name": "pagina1 foo", "Title": "Probando el KO bar" }
Run Code Online (Sandbox Code Playgroud)

它只会更新这些属性.但是,如果您使用以下内容重新映射,则对集合进行不同的处理.

{ "Name": "pagina1 foo", "Title": "Probando el KO bar", 
  Controls: [ { // snip some updated object } ] }
Run Code Online (Sandbox Code Playgroud)

它将删除Controls集合中的不匹配项,而不是更新匹配项.实现此功能的唯一方法是遍历集合并映射您要更新的每个项目.您的代码几乎是在正确的轨道上我相信它应该是

ko.mapping.fromJS(updatedControl, viewModel.Controls()[0])
Run Code Online (Sandbox Code Playgroud)

编辑

你错过了fromJS调用的中间映射参数.

http://jsfiddle.net/3CtFq/

映射对象通常是可选的,但我想如果您正在映射子对象,则插件无法判断此子项父级最初是否映射为无选项.

希望这可以帮助.