我有很多要创建的集合,并且不想为每个entry_type创建FormType,因为它们只使用一次.
因此,我没有在entry_type选项中给出表单类型FQCN,而是尝试直接从表单生成器中添加一个新的Type:
$type = $this
->get('form.factory')
->createBuilder(Type\FormType::class)
->add('label', Type\TextType::class, [
'label' => 'Key',
])
->add('value', Type\TextType::class, [
'label' => 'Value',
])
->getType()
;
$form = $this
->get('form.factory')
->createBuilder(Type\FormType::class)
->add('hash', Type\CollectionType::class, [
'entry_type' => $type,
'entry_options' => [],
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'required' => false,
'delete_empty' => true,
])
->getForm()
;
但由于某些原因,原型无效:
<div class="form-group">
<label class="control-label required">__name__label__</label>
<div id="form_hash___name__"></div>
</div>
我手动创建的$type中的所有子字段都将丢失.我的错误在哪里?
解决方法:
我终于找到了答案.
由于我使用的 – > getType()是在FormBuilder类中,而不是在FormBuilderInterface中,我认为使用它是个坏主意.此外,返回的FormType实例为空(表单类型,但没有子项).
所以我改变了我的立场并创建了以下EntryType类(是的,我使用的是Form Type类,但是对于我以后的所有集合只使用了一个类):
<?PHP
namespace AppBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class EntryType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
foreach ($options['fields'] as $field) {
$builder->add($field['name'], $field['type'], $field['options']);
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'fields' => [],
]);
}
}
我现在可以使用以下字段选项在我的集合中使用任意字段:
use Symfony\Component\Form\Extension\Core\Type;
use AppBundle\Form\Type\EntryType;
// ...
$form = $this
->get('form.factory')
->createBuilder(Type\FormType::class)
->add('hash', Type\CollectionType::class, [
'entry_type' => EntryType::class,
'entry_options' => [
'fields' => [
[
'name' => 'key',
'type' => Type\TextType::class,
'options' => [
'label' => 'Key',
],
], [
'name' => 'value',
'type' => Type\TextType::class,
'options' => [
'label' => 'Value',
],
],
],
],
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'required' => false,
'delete_empty' => true,
])
->getForm()
;