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

Posted

技术标签:

【中文标题】HTML在构造参数时遵循啥规则?【英文标题】:What rules does HTML follow when constructing parameters?HTML在构造参数时遵循什么规则? 【发布时间】:2016-10-04 03:17:16 【问题描述】:

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

渲染出来的html如下:

<td  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  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>

在这种情况下,第一个 &lt;td&gt; 正在修改 id 为 1 的现有记录,而第二个 &lt;td&gt; 正在提供创建新记录的参数。创建新记录时,还会创建子 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"
]

不知何故,&lt;td&gt; 边界不起作用,子 charged_amount 属性不知何故被归入第一个 &lt;td&gt; 现有记录修改中。

谢谢!

【问题讨论】:

您能否也发布您用于生成此标记的 RoR 代码? 能否提供您浏览器提交的原始POST数据?最简单的方法是从浏览器开发者工具的“网络”窗格中获取。 【参考方案1】:

不是&lt;td&gt; 或任何类似的HTML 元素构成输入的“边界”,它只是&lt;form&gt; element&lt;form&gt; 标签内的所有输入都由浏览器在提交表单时作为参数发送。您可能在一个 &lt;form&gt; 中有两列,这就是为什么两列的参数在 params 中混合使用。

【讨论】:

很抱歉,您不确定您是否理解了这个问题。我确实希望这两个参数都以一种形式出现。但我需要它们以不同于现在的方式嵌套【参考方案2】:

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

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

希望这会引导您朝着正确的方向前进。

【讨论】:

【参考方案3】:

我不确定是否有一种方法可以根据您的需要专门执行此操作,但您可以使参数看起来像这样:

"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  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 中从上到下)获取属性,并在每次看到重复属性时创建一个新对象。

【讨论】:

以上是关于HTML在构造参数时遵循啥规则?的主要内容,如果未能解决你的问题,请参考以下文章

13. 多重继承

Amazon S3 重定向规则 - 保留查询参数

C++调用父类的构造函数规则

Apache Commons Digester 二(规则模块绑定-RulesModule异步解析-asyncParsexml变量Substitutor带参构造方法)

第18课构造函数(中)

C++运算符重载时要遵循的规则