我对How to stop Form->handleRequest from nulling fields that don't exist in post data提出了完全相反的问题。
我有一个动态表单,允许用户动态添加和删除表单中的字段。
表单允许用户创建新实体或编辑实体。在创作时,没有问题。但是,在版本上,当我使用$form->getData();
时,我可以获得具有无效属性的实体。
例如:我有Vehicle
个实体可以拥有以下值
Type
:自行车,摩托车,汽车Fuel
:integer
表单将删除" Fuel"当我们选择" Bicycle"。但是,如果在版本之前,车辆是" Car"使用8 fuel
,即使表单删除字段,$form->getData();
也会返回类型为Bicycle
和8 fuel
的对象。
根据要求,这是FormType:
class VehicleType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$formModifier = function (FormInterface $form, $fields = null, array $options) {
foreach ($fields as $field_id => $field_value) {
if ($field_id == 'vehicle') {
if ($field_value && ('car' == $field_value)) {
$form->add('gas');
} else {
$form->remove('gas');
}
}
}
};
$builder->addEventListener(
FormEvents::PRE_SUBMIT,
function (FormEvent $event) use ($formModifier, $options) {
$formModifier($event->getForm(), $event->getData(), $options);
}
);
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifier, $options) {
$vehicle = $event->getData();
$formModifier($event->getForm(), array(
'vehicle' => $vehicle->getVehicle(),
), $options);
}
);
$builder->add('vehicle', ChoiceType::class, array(
'choices' => array(
'bicycle' => 'bicycle',
'car' => 'car',
)
));
$builder->add('add', SubmitType::class);
}
}
实体并不特别:
class Vehicle
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*
*/
private $id;
/**
* @var int
*
* @ORM\Column(name="vehicle", type="string", length=255)
*/
private $vehicle;
/**
* @var string
*
* @ORM\Column(name="gas", type="smallint", nullable=true)
*/
private $gas;
(...)
然后,控制器:
/**
* @Route("/vehicle-add", name="vehicle_add")
*/
public function vehicleAddAction(Request $request)
{
$vehicle = new Vehicle();
$form = $this->createForm(VehicleType::class, $vehicle);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$vehicle = $form->getData();
$em = $this->getDoctrine()->getManager();
$em->persist($vehicle);
$em->flush();
}
return $this->render('default/vehicle-add.html.twig', array(
'form' => $form->createView(),
));
}
/**
* @Route("/vehicle-edit", name="vehicle_edit")
*/
public function vehicleEditAction(Request $request)
{
$vehicle = $this->getDoctrine()->getRepository('AppBundle:Vehicle')->findOneBy(array('id' => 1));
$form = $this->createForm(VehicleType::class, $vehicle);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$vehicle = $form->getData();
$em = $this->getDoctrine()->getManager();
$em->persist($vehicle);
$em->flush();
}
return $this->render('default/vehicle-edit.html.twig', array(
'form' => $form->createView(),
));
}