【问题标题】:How do handle empty arrays when serializing only altered form elements仅序列化更改的表单元素时如何处理空数组
【发布时间】:2017-05-14 23:19:55
【问题描述】:

我有一个包含多个多选字段的表单。每个选择都有一个唯一的 ID,并相应地命名:

values[foobar1][]
values[foobar2][]
values[foobar3][]
... etc.

此表单可能包含数百个这样的字段,因此由 ajax 分页。其结果是无法保证所有记录都会在前端立即可用。因此,我不可能提交整个表格。但是,我确实可以访问服务器端的整个记录​​列表。

我对此的解决方案是观察表单字段的变化,并且对于每个发生变化的字段,将值存储在一个数组中以仅跟踪更改的字段值。因此,如果您仅更改 foobar2,则发送到服务器的结果序列化数组将如下所示:

0: Object {
    name: "values[foobar2][]"
    value: "thevalue1"
},
1: Object {
    name: "values[foobar2][]"
    value: "thevalue3"
}

So this works fine except for, as you may have guessed, when the select multiple is emptied.无论我使用什么格式来存储更改的值,无论是每个字段的 arraySerialization 还是作为关联数组,当我将数组传递给 $.param() 以进行 ajax 请求时,生成的序列化字符串都不包含空值的痕迹.所以服务器无法判断该值已被清空。

任何人都可以提出一种将数据传递到服务器以使 empt(ied) 数组保持完整的方法,或者另一种处理初始问题的方法。

提前致谢!

【问题讨论】:

  • 您是否还可以沿<input type="hidden" name="the name of the field here" /> 的行添加隐藏输入,然后您可以检查数组中是否存在这些值,如果它们不存在,则它们为空。每个选择菜单都有一个隐藏的输入
  • 这似乎是最简单的解决方案。我想与其使用硬编码的隐藏字段,不如只传递一个带有字段值的更改字段键的辅助数组。听起来像我要走的路线!

标签: javascript php jquery arrays ajax


【解决方案1】:

您想要计算当前状态和先前状态之间的差异,将更改发送到服务器,并将其应用于数据。

您可以使用JSON patch 标准 (rfc6902) 执行此操作。

JSON Patch 是一种描述 JSON 文档更改的格式。它 可用于避免在只有一部分有时发送整个文档 改变了。当与 HTTP PATCH 方法结合使用时,它允许 以符合标准的方式对 HTTP API 进行部分更新。

要创建差异,您可以使用 NPM 模块,例如 jiff。 diff 是一组修补命令,可以转换 JSON 文档。例如:

[
  { "op": "replace", "path": "/values/foobar2/", "value": ["thevalue1"] },
  { "op": "remove", "path": "/values/foobar2/"}
]

您将差异发送到服务器,然后使用服务器模块(例如php-jsonpatch)将补丁应用于服务器上的当前数据。

【讨论】:

    【解决方案2】:

    为所有选择字段值创建一个对象,您可以使用localStoragesessionStorage 来存储它。由于表单位于很多页面中,并且您使用 ajax 来获取每个选择字段。将每个字段的选定值放在一个数组中。创建一个像这样的对象就是这个想法。

    { 
    formValues: {
              foobar1: {
                       values: ["thevalue1","thevalue2"]
                       },
              foobar2: {
                       values: ["thevalue3"]
                       },
            ...
              foobarN: {
                       values: []
                       }           
                 }
    }
    

    每次更新一个或多个选定字段值时,请确保更新 localStorage 保存的值。例如

    var valuesObject = { 
                  formValues: {
                              foobar1: {
                                       values: ["thevalue1","thevalue2"]
                                       },
                              foobar2: {
                                       values: ["thevalue3"]
                                       },
                              foobar3: {
                                       values: []
                                       }           
                              }
                         }
    
    // Put the object into storage
    localStorage.setItem('valuesObject', JSON.stringify(valuesObject));
    
    // Retrieve the object from storage
    var valuesObjectA = localStorage.getItem('valuesObject');
    //console.log('valuesObject: ', JSON.parse(valuesObjectA));
    // post your data
    $.post( "ajax.php", valuesObjectA ).done(function( data ) {
    alert( "Data Loaded: " + data );
    }).fail(function() {
    console.log( "error" );
    });
    

    示例fiddle

    【讨论】:

    • 是的,这基本上就是我到目前为止所做的事情。问题是,一旦我序列化它以使用 ajax 发送,序列化不包括任何关于 foobarN 在你的例子。所以服务器不知道它被触摸了。
    • @Raiden616 你的意思是foobarN 根本不包括,因为它是空的?请检查更新的答案,以更清楚地了解我的意思。
    猜你喜欢
    • 1970-01-01
    • 2012-01-03
    • 1970-01-01
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-21
    相关资源
    最近更新 更多