Symfony版本:3.4
我有一个根形式是布局形式,其中包括一个被称为块的集合类型。内容形式属于块形式。我想使用ajax来使用户更改选择器1的值,然后将窗体类型2更改为其他窗体类型。
可以在$ request->控制器中的请求中选择更新后的选定值。
但是我无法获得选择器1的新数据,它始终是旧数据。
LayoutType.php
class LayoutType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name', TextType::class, array(
'attr' => array(
'class' => 'form-control'
),
'label' => 'name'
));
$builder->add('blocks', CollectionType::class, array(
'entry_type' => BlockType::class,
'entry_options' => array('label' => false),
'allow_add' => true,
'allow_delete' => true,
'required' => false,
'label' => false
));
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => '****\Bundle\****Bundle\Entity\Layout'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'layout_form';
}
}
BlockType.php
class BlockType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name', TextType::class, array(
'attr' => array(
'class' => 'form-control layout-block-name'
),
'label' => '名称'
));
$builder->add('contents', CollectionType::class, array(
'entry_type' => BlockContentType::class,
'entry_options' => array('label' => false),
'allow_add' => true,
'allow_delete' => true,
'required' => false,
'label' => false
));
}/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => '****\Bundle\****Bundle\Entity\LayoutBlock'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'layout_block_form';
}
}
BlockContentType.php
class BlockContentType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$factory = $builder->getFormFactory();
$builder->addEventSubscriber(new BlockContentValueFieldSubscriber($factory));
$builder->add('unit', TextType::class, array(
'attr' => array(
'class' => 'form-control block-content-unit',
'placeholder' => '默认单位'
),
'required' => false,
'label' => '默认单位'
));
$builder->add('option', EntityType::class, array(
'class' => '*******Bundle:FormFieldOption',
'choice_label' => 'name',
'attr' => array(
'class' => 'form-control'
),
'label' => '表单选项'
));
$builder->add('type', ChoiceType::class, array(
'attr' => array(
'class' => 'form-control select-block-content-form-type'
),
'choices' => array(
'文本' => 'textarea',
'下拉菜单' => 'select',
'图片' => 'image'
),
'preferred_choices' => array('textarea'),
'label' => 'Form TYpe'
));
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => '****\Bundle\****Bundle\Entity\LayoutBlockContent'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'block_content_form';
}
}
BlockContentValueFieldSubscriber.php
class BlockContentValueFieldSubscriber implements EventSubscriberInterface
{
protected $factory;
public function __construct(FormFactoryInterface $factory)
{
$this->factory = $factory;
}
public static function getSubscribedEvents()
{
return array(
FormEvents::PRE_SET_DATA => 'preSetData',
);
}
public function preSetData(FormEvent $event)
{
$data = $event->getData();
$form = $event->getForm();
if (!($data instanceof LayoutBlockContent) || !$data->getBlock()) {
$form->add('value', TextareaType::class, array(
'attr' => array(
'class' => 'form-control block-content-input-value form-textarea-type'
)
));
} else {
$type = $data->getType();
// $type always is old data not the ajax data
switch ($type)
{
case 'image':
$form->add('value', FileType::class, array(
'data_class' => null,
'attr' => array(
'class' => 'form-control block-content-input-value form-image-type'
)
));
break;
default:
$form->add('value', TextareaType::class, array(
'attr' => array(
'class' => 'form-control block-content-input-value form-textarea-type'
)
));
break;
}
}
}
}