[英]Array to CollectionType in Symfony 3.4 forms
我有實體的數組 Cart,我想生成一般形式,它看起來像在屏幕上。
如您所見,我希望每一行都有可編輯的字段 Quantity,它代表 Cart 實體,並且我希望能夠一次更新所有這些字段。
class Cart
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="carts")
*/
private $userId;
/**
* @ORM\ManyToOne(targetEntity="Product", inversedBy="carts")
*/
protected $product;
/**
* @ORM\Column(type="integer")
*/
private $quantity;
/*gettes & setters */
}
現在,我有想要接收 CollectionType 的表單來處理它,但是 - 我只有一個實體數組,所以它正在轉儲 LogicalException。
我需要做什么 - 有什么方法可以將數組解析為 CollectionType,或者我可以用另一種方式從數據庫中獲取一組購物車實體?:
$carts=$this->getDoctrine()->getRepository(Cart::class)->findByUserId($user);
在有關如何嵌入表單集合的Symfony 文檔中,有一個示例說明如何執行您希望實現的目標。
對於您的特定用例,您需要創建一個UserCartsForm
和一個單獨的CartsForm
。
在您的UserCart
將carts
字段添加為CollectionType
。 然后 Symfony 會將該字段作為一系列表單進行處理。
src/AppBundle/Form/UserCart.php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type as FormType;
class UserCartsForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('carts', FormType\CollectionType::class, [
'label' => false,
'entry_type' => CartsForm::class,
'entry_options' => array('label' => false),
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
]);
}
}
將您想要在表單上編輯的字段添加到 CartsForm
src/AppBundle/Form/CartsForm.php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type as FormType;
class CartsForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('quantity', FormType\IntegerType::class, [
'label' => false
//...
]);
//...
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Cart::class,
]);
}
}
在您的控制器中,將用戶實體引用為您的UserCartsForm
數據。
src/AppBundle/Controller/DefaultController.php
namespace AppBundle\Controller;
use AppBundle\Form\UserCartsForm;
class DefaultController extends Controller
{
/**
* @Route('/user/{id}/carts')
*/
public function userCartsAction(Request $request, User $user)
{
$form = $this->createForm(UserCartsForm::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
//... process entity
//$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('some_route');
}
return $this->render('user_carts_form.html.twig', [
'form' => $form
]);
}
}
然后,您應該能夠輕松地從樹枝模板中檢索數據以按照您的意願進行渲染。
應用程序/資源/視圖/user_carts_form.html.twig
{% form_start(form) %}
<table>
<thead>
<tr>
<td>Name</td>
<td>Quantity</td>
<td></td>
</tr>
</thead>
<tbody>
{% for cart in form.carts %}
{% set cartEntity = cart.vars.data %}
<tr>
<td>{{ cartEntity.product.name }}</td>
<td>{{ form_widget(cart.quantity) }}</td>
<td><a class="button" href="{{ path('remove_cart_action', { id: cartEntity.id }) }}">Delete <icon/></a></td>
<tr>
{% endfor %}
</tbody>
</table>
<button type="submit">Submit</button>
{% form_end(form) %}
實體約束更新
默認情況下,Symfony 將在驗證表單時使用分配給實體的所有約束( Default
),導致$form->isValid()
返回 false。
https://symfony.com/doc/3.4/validation/groups.html
如果未指定組,則將應用屬於組
Default
所有約束。
要解決此問題,請使用驗證組來分離實體約束並在其各自的表單上聲明所需的組。
例子:
src/AppBundle/Entity/User.php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
*/
class User
{
/**
* @Assert\NotBlank(groups={"registration"})
*/
private $username;
//...
}
然后要在所需表單上使用您的驗證組,在本例中為RegistrationForm
,您在AbstractTye::configureOptions
中將所需組聲明為OptionsResolver:$defaults
。
src/AppBundle/Form/RegistrationForm.php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
class RegistrationForm extends AbstractType
{
//...
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
'validation_groups' => ['registration']
]);
}
}
現在User::NotBlank
約束將僅適用於RegistrationForm::isValid()
或任何其他聲明注冊驗證組的表單。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.