【发布时间】:2018-02-26 10:46:03
【问题描述】:
我是 Symfony 的初学者,所以这个问题对于那些在这个框架方面更有经验的人来说可能很简单。
我正在构建表单,并且我在表单中有几种可能的项目类型。目前这些是:
- 文字
- html
- 图片
但是,将来会有更多的项目。以前,该项目将所有项目生成到它们的位置(文本、html 和图像)并隐藏特定表单项不需要的那些(最多需要一个)。但是,我打算避免添加我不需要的项目。由于我不知道任意项目的buildForm 是否正在运行它是文本、html 还是图像,所以此时所有这些都被添加(我知道这是违反直觉的,但这是我的代码尝试重构):
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('layoutTypeInput', TextType::class);
$builder->add('blockTypeOutput', EntityType::class, array(
'class' => 'MyPageBundle:BlockTypeOutput',
'choice_label' => 'titleHu',
'required' => false,
'placeholder' => 'Válassz blokk kimenetet!',
'empty_data' => null,
));
$builder->add('text', TextType::class, $this->getBlockTypeOptions('text'));
$builder->add('html', TextareaType::class, $this->getBlockTypeOptions('html'));
$builder->add('image', ImageSelectType::class, $this->getBlockTypeOptions('image'));
$builder->addEventListener(FormEvents::POST_SET_DATA, array($this, 'onPostSetData'));
$builder->addEventListener(FormEvents::PRE_SUBMIT, array($this, 'onPreSubmit'));
}
现在,我有一个函数可以删除 form 的不必要元素:
private function removeUnnecessaryItems(\Symfony\Component\Form\FormInterface $form, $key)
{
$keys = ['text', 'html', 'image'];
foreach ($keys as $k) {
if ($key !== $k) $form->remove($k);
}
}
在onPostSetData里面我这样称呼它:
$this->removeUnnecessaryItems($form, $inputObject->getLayoutTypeIdText());
最后,在 twig 中,我确定应该在表单中生成什么:
{% for ioLayoutBlock in form.ioLayoutBlocks %}
<div class="row">
<div class="col-xs-12 col-md-3">
{{ form_errors(ioLayoutBlock.layoutTypeInput) }}
{{ioLayoutBlock.layoutTypeInput.vars.label}}
</div>
{{ form_widget(ioLayoutBlock.layoutTypeInput, {'attr' : {'class':'hidden'}}) }}
<div class="col-xs-12 col-sm-6 col-md-5">
{{ form_errors(ioLayoutBlock.blockTypeOutput) }}
{{ form_widget(ioLayoutBlock.blockTypeOutput, {'attr' : {'class':'blockTypeOutput'}}) }}
</div>
<div class="col-xs-12 col-sm-6 col-md-4">
{% if ioLayoutBlock.text is defined %}
{{ form_errors(ioLayoutBlock.text) }}
{{ form_widget(ioLayoutBlock.text, {'attr':{'class':'hidden uniqueInput ioLayoutBlock_text' }}) }}
{% elseif ioLayoutBlock.html is defined %}
{{ form_errors(ioLayoutBlock.html) }}
{% if layout.layoutType.name == 'userHTML' %}
<div class="input-group ioLayoutBlock_html hidden">
<a class="input-group-addon myAdminForm" target="_blank" data-my-href="page/{{ page.id }}/wysiwyg/{{ layout.id }}"><span class="glyphicon glyphicon-pencil"></span></a>
{{ form_widget(ioLayoutBlock.html, {'attr':{'class':'uniqueInput wysiwyg' }}) }}
</div>
{% else %}
{{ form_widget(ioLayoutBlock.html, {'attr':{'class':'hidden uniqueInput wysiwyg ioLayoutBlock_html' }}) }}
{% endif %}
{% elseif ioLayoutBlock.image is defined %}
{{ form_errors(ioLayoutBlock.image) }}
{{ form_widget(ioLayoutBlock.image, {'attr':{'class':'hidden uniqueInput ioLayoutBlock_image' }}) }}
{% endif %}
</div>
</div>
{% endfor %}
如果我加载页面,一切都会正确显示,但不幸的是,当我尝试提交 form 时,它给出了错误
此表单不应包含额外字段。
我拥有的 form 项目数是我的数倍。如果我在 onPostSetData 内注释掉对 removeUnnecessaryItems 的调用,然后从树枝中删除条件,例如:
{% if ioLayoutBlock.text is defined %}
然后一切正常,但这就是重构之前的工作方式。理想情况下,我想避免在buildForm 添加这么多不必要的东西,但我不知道如何在那里加载任何有意义的数据来确定项目的类型。或者,我想确保在我知道它们的类型的事件中成功删除这些项目,而不会出现上述提交时的表单错误。所以,我的问题是:如何避免在表单中生成各种不必要的东西而不会被提交错误阻止?
【问题讨论】:
-
是否有域规则要求您在创建表单后删除表单项?或者它只是按照它已经完成的方式?
-
@goto 我认为它已经完成了,但我对项目和 Symfony 都是新手,所以我可能会遗漏一些东西。
标签: php symfony symfony-2.8