Symfony 4.3 Multiple ChoiceType 使用PATCH时只能加值不能移除
Symfony 4.3 Multiple ChoiceType can only add values and not remove when using PATCH
给定形式:
...
$builder
->add('testArray', ChoiceType::class, [
'choices' => ['ROLE_ADMIN' => 'ROLE_ADMIN', 'ROLE_USER' => 'ROLE_USER'],
'expanded' => true,
'multiple' => true
])
;
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => TestEntity::class,
'csrf_protection' => false,
'method' => 'PATCH'
]);
}
...
和实体:
...
/**
* @ORM\Column(type="simple_array", nullable=true)
*/
private $testArray = [];
public function getTestArray(): ?array
{
return $this->testArray;
}
public function setTestArray(?array $testArray): self
{
$this->testArray = $testArray;
return $this;
}
...
通过添加值提交表单时...一切正常。
但是当删除值时...值不会被删除,并且永远不会调用 setter。
奇怪的是,将表单方法切换为 GET 可以解决此问题。
怎么回事?
---编辑---
这是重现此问题的控制器:
/**
* @Route("/{id}/edit", name="test_entity_edit", methods={"GET","POST","PATCH"})
*/
public function edit(Request $request, TestEntity $testEntity): Response
{
$form = $this->createForm(TestEntityType::class, $testEntity);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('test_entity_index', [
'id' => $testEntity->getId(),
]);
}
return $this->render('test_entity/edit.html.twig', [
'test_entity' => $testEntity,
'form' => $form->createView(),
]);
}
----编辑----
使用 POST 进行测试非常有效。但是使用 PATCH 它失败了。所有其他字段都会更新。并添加到数组中。但是从数组中删除不会。我在上面添加了相关的 PATCH 代码并更新了标题以澄清问题。
我不确定这是否是您的全部问题,但是当您处理表单提交时,您并没有保留实体。
$this-getDoctrine()->getManager()->flush();
正常写
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($testEntity);
$entityManager->flush();
见https://symfony.com/doc/current/best_practices/forms.html#handling-form-submits
似乎 PATCH
在涉及数组时不明确,并且有多种处理发送数据的方法。
Symfony 在调用 submit()
时会检测到 PATCH
而不是 $clearMissing
(不会清空数据中缺失的实体字段)。说到数组,这是有歧义的。
为了解决这个问题,我不再使用 PATCH 来更新用户实体,而是转向了这个解决方案 Symfony2: Edit user without having password
这基本上使用了两种不同的 FormType,一种用于创建用户,另一种用于编辑它。每种表单类型使用不同的验证组。允许在不提交或清除用户密码的情况下编辑用户。
给定形式:
...
$builder
->add('testArray', ChoiceType::class, [
'choices' => ['ROLE_ADMIN' => 'ROLE_ADMIN', 'ROLE_USER' => 'ROLE_USER'],
'expanded' => true,
'multiple' => true
])
;
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => TestEntity::class,
'csrf_protection' => false,
'method' => 'PATCH'
]);
}
...
和实体:
...
/**
* @ORM\Column(type="simple_array", nullable=true)
*/
private $testArray = [];
public function getTestArray(): ?array
{
return $this->testArray;
}
public function setTestArray(?array $testArray): self
{
$this->testArray = $testArray;
return $this;
}
...
通过添加值提交表单时...一切正常。 但是当删除值时...值不会被删除,并且永远不会调用 setter。
奇怪的是,将表单方法切换为 GET 可以解决此问题。
怎么回事?
---编辑---
这是重现此问题的控制器:
/**
* @Route("/{id}/edit", name="test_entity_edit", methods={"GET","POST","PATCH"})
*/
public function edit(Request $request, TestEntity $testEntity): Response
{
$form = $this->createForm(TestEntityType::class, $testEntity);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('test_entity_index', [
'id' => $testEntity->getId(),
]);
}
return $this->render('test_entity/edit.html.twig', [
'test_entity' => $testEntity,
'form' => $form->createView(),
]);
}
----编辑----
使用 POST 进行测试非常有效。但是使用 PATCH 它失败了。所有其他字段都会更新。并添加到数组中。但是从数组中删除不会。我在上面添加了相关的 PATCH 代码并更新了标题以澄清问题。
我不确定这是否是您的全部问题,但是当您处理表单提交时,您并没有保留实体。
$this-getDoctrine()->getManager()->flush();
正常写
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($testEntity);
$entityManager->flush();
见https://symfony.com/doc/current/best_practices/forms.html#handling-form-submits
似乎 PATCH
在涉及数组时不明确,并且有多种处理发送数据的方法。
Symfony 在调用 submit()
时会检测到 PATCH
而不是 $clearMissing
(不会清空数据中缺失的实体字段)。说到数组,这是有歧义的。
为了解决这个问题,我不再使用 PATCH 来更新用户实体,而是转向了这个解决方案 Symfony2: Edit user without having password
这基本上使用了两种不同的 FormType,一种用于创建用户,另一种用于编辑它。每种表单类型使用不同的验证组。允许在不提交或清除用户密码的情况下编辑用户。