列表行

list 字段的行如何验证


list 字段包含多行;每一行都是其子表单的一个实例,通过行 编辑器填写。带有 subform 的 yaml 字段就相当于这样的一行。服务器处理它们的方式 与浏览器的行编辑器相同:每一行都通过其子表单解析,表单的值 作为 __parent__ ,检查其规则,并对其计算字段求值。嵌套列表的处理方式 也一样:在某一行自己的列表中, $(__parent__.__parent__.x) 可以访问到表单。

行的检查方式如下:

  • 用户在编辑器中添加或编辑的行会被解析和验证。
  • 没有人动过的行,即由列表自身的默认值、表达式或查询生成的行 (例如 ACL 列表中已有的条目),会原样通过,与浏览器中 一样:不会重新验证,也不会添加任何内容。已有条目即使违反了 后来编写的规则,也不会阻止运行。
  • 标记为已删除的行(列表的 deleteMarker )保持原样,不做验证。

为了在不信任请求的前提下区分这些行,服务器会在运行验证中再次运行列表自身的 数据来源(其默认值,否则是其表达式或查询)。没有经过编辑器的行 只有在属于该数据来源所生成的行时才会原样通过。其他任何行,例如 REST 调用方凭空编造的行,都会像 编辑过的行一样被解析和验证。因此普通的行无法绕过检查,而 浏览器中未改动的行仍然会原样通过。

浏览器用户只会在一种情况下注意到这一点:在打开表单到运行表单之间,数据来源的数据发生了变化 (期间某个条目被修改或删除),并且该行 违反了其子表单的某条规则。这时该行不再算作数据来源中的行,因此 会被验证,运行会被拒绝,并指出该行,例如 acls[2].user_or_group (regex) 。

验证失败的行会出现在 rowErrors 中,带有其 index ( yaml 字段没有),并在日志中显示为 disks[1].size (maxValue) 。

一次运行在所有嵌套层级中最多可包含 500 行,因为每一行都会运行其子表单的查询。


行标记

列表在其行上设置的标记( insertMarker 、 updateMarker 和 deleteMarker ;如果没有 insertMarker ,当列表设置了 allowDelete: false 、 deleteMarker 或 updateMarker 时,新行会得到 __inserted__ ) 会随每个带标记的行传给 playbook。被移除的行会带着其删除 标记发送,这样 playbook 就可以删除它。在 6.4.1 之前,只有当子表单把标记声明为(隐藏)字段时, 列表行才会带有该标记。