HTML在构造参数时遵循哪些规则?

时间:2016-06-03 23:28:17

标签: html ruby-on-rails nested-forms nested-attributes named-parameters

我使用Rails基于一组复杂的嵌套属性自动神奇地创建子对象。因此,我需要以非常特殊的方式嵌套参数。显然我意识到我可以用JS构建它们,但是我喜欢表单的顺序来自动帮助构造。对于上下文,我有2列,由2 <td> s表示。每列可以创建新记录或编辑现有记录。当然,当要修改现有记录时,必须传递记录的ID。

呈现的HTML如下:

<td width="50%" style="padding-right:3%" class="logistic-details" data-type="logistics" data-typelogistics="delivery" data-instructions="test instructions" data-id="1" data-amount="20">
  <span class="area-to-inject-amount-inputs" data-object="type_logistics" data-type="logistics" data-typelogistics="delivery">
    <input class="labeler-response" name="type_logistics_attributes[][id]" type="hidden" value="1">
    <input class="labeler-response" name="type_logistics_attributes[][instructions]" type="text" value="test instructions">
  </span>
</td>

<td width="50%" style="padding-right:3%" class="logistic-details" data-type="logistics" data-typelogistics="pickup" data-instructions="" data-id="" data-amount="0">
  <span class="area-to-inject-amount-inputs" data-object="type_logistics" data-type="logistics" data-typelogistics="pickup" data-actioned="charged">
    <input type="hidden" name="type_logistics_attributes[][type_of_logistics]" value="pickup">
    <input class="injected-amount-input" type="number" min="0" max="" placeholder="Amount" name="type_logistics_attributes[][charged_amounts_attributes][][amount]" value="20">
    <span class="area-to-inject-type-of-amount">
      <input type="hidden" name="type_logistics_attributes[][charged_amounts_attributes][][type_of_amount]" value="logistics">
    </span>
    <input class="labeler-response" name="type_logistics_attributes[][instructions]" type="text" placeholder="Enter address and instructions">
  </span>                      
</td>

在这种情况下,第一个<td>正在修改id为1的现有记录,而第二个<td>正在提供创建新记录的参数。创建新记录时,还会创建子charged_amounts。因此,这些是我期望的参数:

"type_logistics_attributes"=>[
  {"id"=>"1", "instructions"=>"test instructions"},
  {"type_of_logistics"=>"pickup", "charged_amounts_attributes"=>[{"amount"=>"40", "type_of_amount"=>"logistics"}], "instructions" => "123 Fake street"}
]

相反,我得到以下内容:

"type_logistics_attributes"=>[
  {"id"=>"1", "type_of_logistics"=>"pickup", "instructions"=>"test instructions", "charged_amounts_attributes"=>[{"amount"=>"40", "type_of_amount"=>"logistics"}]}, 
  {"instructions"=>"123 Fake street"}
]

不知何故,<td>边界不起作用,并且子charged_amount属性以某种方式被归入第一个<td>现有记录修改。

谢谢!

3 个答案:

答案 0 :(得分:3)

不是<td>或任何类似的HTML元素为输入设置“边界”,它只是 <form> element 。在提交表单时,浏览器会将<form>标记内的所有输入作为参数发送。您可能在一个<form>中同时包含两列,这就是为什么两列中的参数混合在params中。

答案 1 :(得分:2)

我知道的唯一方法是,您可以在一个表单中获取两个参数但嵌套方式不同的是,如果您为新输入字段提供了一些id。这就是区分type_logistics_attributes数组元素的原因。

我有类似的需求,我使用了ryanb's nested form。当我将它用于与你相同的目的时,它的作用是,它为新的输入字段提供随机id。这就是它的区别。

希望这能引导你朝着正确的方向前进。

答案 2 :(得分:-1)

我不确定是否有办法按照你的意愿专门做,但你可以让params看起来像这样:

"type_logistics_attributes"=>[
  {"id"=>"1", "instructions"=>"test instructions"},
  {"id"=>"1", "type_of_logistics"=>"pickup", "charged_amounts_attributes"=>[{"amount"=>"40", "type_of_amount"=>"logistics"}], "instructions" => "123 Fake street"}
]

您可以通过在此处添加其他隐藏输入重复ID来实现它:

<td width="50%" style="padding-right:3%" class="logistic-details" data-type="logistics" data-typelogistics="pickup" data-instructions="" data-id="" data-amount="0">
  <span class="area-to-inject-amount-inputs" data-object="type_logistics" data-type="logistics" data-typelogistics="pickup" data-actioned="charged">
    <input name="type_logistics_attributes[][id]" type="hidden" value="1">
    <input type="hidden" name="type_logistics_attributes[][type_of_logistics]" value="pickup">
    <input class="injected-amount-input" type="number" min="0" max="" placeholder="Amount" name="type_logistics_attributes[][charged_amounts_attributes][][amount]" value="20">
    <span class="area-to-inject-type-of-amount">
      <input type="hidden" name="type_logistics_attributes[][charged_amounts_attributes][][type_of_amount]" value="logistics">
    </span>
    <input class="labeler-response" name="type_logistics_attributes[][instructions]" type="text" placeholder="Enter address and instructions">
  </span>                      
</td>

Rails有一个处理这个问题的规则:它在查询字符串中从左到右采用属性(或在HTML中从上到下),并在每次看到重复属性时创建一个新对象。