Extbase:使同一页面上修改同一对象的两个表单具有单独的验证错误和用户输入



我有一个Parent对象,它具有ObjectStorage类型的$children属性,它保存了Child对象的集合。

页面包含两个流体表单,指向同一个saveAction(),无论第一个表单是否接受$children属性的文件上传(CSV-file),第二个表单是否接受输入列表

简化如下:

<f:form action="save" name="parent" object="{parent}" enctype="multipart/form-data">
    <f:form.validationResults for="parent">
    error output
    </f:form.validationResults>
    <f:form.upload property="children" />
    <f:form.submit />
</f:form>
<f:form action="save" name="parent" object="{parent}">
    <f:form.validationResults for="parent">
    error output
    </f:form.validationResults>
    <f:form.textfield property="children.0.title" />
    <f:form.textfield property="children.1.title" />
    <f:form.textfield property="children.2.title" />
    <f:form.textfield property="children.3.title" />
    <f:form.textfield property="children.4.title" />
    <f:form.submit />
</f:form>

两个窗体都在为父窗体创建子对象。

除了出现验证错误(文件格式错误,子标题不正确等)的情况外,所有工作正常。然后,无论从哪个表单提交,验证错误都会显示在两个表单中。此外,CSV-file中的解析标题显示在第二种形式的输入中。

我可以看到这样做的原因:请求参数parent取自表单的名称,并且它们都是相同的。但是,如果我在其中一个表单中重命名它,PropertyMapper将不再找到一个动作变量来映射重命名的属性。

我发现,属性映射配置允许设置属性映射,所以我将<f:form.upload property="children" />更改为<f:form.upload property="childrenFile" />,然后在initializeSaveAction()中设置映射:

$this->arguments['parent']
    ->getPropertyMappingConfiguration()
    ->setMapping('childrenFile', 'children');

但是它只帮助Property Mapper识别目标属性名称,并且所有验证结果仍然显示在<f:form.validationResults for="parent.children">下,而不是我所期望的parent.childrenFile下。

我现在看到的唯一肮脏的解决方案是有两个不同的动作(所以不同形式的name属性)具有不同的参数名称,但实际上是相同的。

这在一个简单的情况下解决了一个问题,但在更复杂的情况下(例如依赖于参数总是被命名为parent,并基于它有一个逻辑,如访问检查),它变得复杂,仍然看起来像一个肮脏的解决方案。

有一个干净的方法来解决这个问题吗?

重命名一个表单的对象和操作,然后您可以分别访问验证错误。

<f:form action="saveUpload" name="uploadParent" object="{parent}" enctype="multipart/form-data">
    <f:form.validationResults for="uploadParent">
    error output
    </f:form.validationResults>
    <f:form.upload property="children" />
    <f:form.submit />
</f:form>
<f:form action="save" name="parent" object="{parent}">
    <f:form.validationResults for="parent">
    error output
    </f:form.validationResults>
    <f:form.textfield property="children.0.title" />
    <f:form.textfield property="children.1.title" />
    <f:form.textfield property="children.2.title" />
    <f:form.textfield property="children.3.title" />
    <f:form.textfield property="children.4.title" />
    <f:form.submit />
</f:form>

现在你需要一个新的动作:

protected function saveUploadAction(Object $uploadParent) {
  $this->forward('save', NULL, NULL, array('parent' => $uploadParent));
}

当然:你的验证也应该在新的saveUploadAction中,所以错误来自于第一个动作之前的forward。

最新更新