阅读了大量文档后,我在这里找到了我的问题的解决方案:http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-form-events-submitted-data
为了使实体不需要,您应该添加事件侦听器并将数据设置为null post submit。
第一步
将orphanRemoval=true 选项添加到您的属性
/**
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Member", orphanRemoval=true, cascade={"persist", "remove"})
* @ORM\JoinColumn(name="parent2_id", referencedColumnName="id",nullable=true)
*/
private $parent2;
第二步
在表单中添加一个新字段,一个未映射的复选框
$builder
->add('parent1', MemberType::class)
->add('withParent2', CheckboxType::class, [
'mapped' => false,
'required' => false,
'data' => true
])
->add('parent2', MemberType::class, [
'required' => false
])
如果未选中,我们将使用此复选框将 parent2 设置为 null。
在此旁边,添加您的事件侦听器:
//this event will set whether or not the checkbox should be checked
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$form = $event->getForm();
$family = $event->getData();
if ($family->getId()) {
$form->add('withParent2', CheckboxType::class, [
'mapped' => false,
'required' => false,
'data' => $family->getParent2() ? true : false
]);
}
});
//Event when the form is submitted, before database update
$builder->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event) {
//if the checkbox was not checked, it means that there was not a second parent
$withParent2 = $event->getForm()->get('withParent2')->getData();
if (!$withParent2) {
// we set this attribute to null, and disable the form validation
$event->getData()->setParent2(null);
$event->stopPropagation();
}
}, 900);
第三步
我们的表单以这种方式工作正常,唯一剩下的问题是 javascript 验证。
只需执行一个 jquery 函数,从您的字段中删除所需的属性。
function toggleParent2Requirement(checked){
if (!checked) {
$("[id^=family_parent2]").prop("required", false);
$("[id^=family_parent2]").attr('disabled', true);
}
else {
$("[id^=family_parent2]").prop("required", true);
$("[id^=family_parent2]").attr('disabled', false);
}
}
在这里,您将 oneToOne 关系设为可选。我唯一不自豪的部分是stopPropagation 部分。这是在文档中,我不知道我们是否只能以更干净的方式禁用该字段的验证。