dropbox1111
2018-04-25 16:42
浏览 88
已采纳

Symfony 3.4表单中的CollectionType数组

I've got the array Cart of the entities, and I want to generate general form, which looks like on the screen.

enter image description here

As you see, I want to have editable field Quantity in each row, which represents the Cart entity, and I want to have ability to update all of them at once.

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 */
}

For now, I have form, which wants to receive CollectionType, to work on it, but - I have only an array of entities, so It's dumping LogicalException.

What I need to do - there is any way to parse array to CollectionType, or maybe I could take group of cart entities from database in another way than that?:

$carts=$this->getDoctrine()->getRepository(Cart::class)->findByUserId($user);

图片转代码服务由CSDN问答提供 功能建议

我有实体的数组Cart,我想生成一般形式,看起来像是 屏幕。

如您所见,我希望每行都有可编辑的字段数量 ,表示Cart实体,我希望能够立即更新所有这些。

  class Cart 
 {
 / ** 
 * @ORM  \ id 
 * @ORM \ Column(type =“integer”)
 * @ORM \ GeneratedValue(strategy =“AUTO”)
 * / 
 nrivate $ id; 
 
 / ** 
 * @  ORM \ ManyToOne(targetEntity =“User”,inversedBy =“carts”)
 * / 
private $ userId; 
 
 / ** 
 * @ORM \ ManyToOne(targetEntity =“Product”,inversedBy =“carts  “)
 * / 
保护$ product; 
 
 / ** 
 * @ORM \ Column(type =”integer“)
 * / 
 nrivate $ quantity; 
 
 / * gettes&  setters * / 
} 
   
 
 

现在,我有一个想要接收CollectionType的表单来处理它,但是 - 我只有一个实体数组 ,所以它正在转储LogicalException。

我需要做什么 - 有什么方法可以将数组解析为CollectionType,或者我可以用另一种方式从数据库中取出一组购物车实体? :

 <代码> $推车= $这 - &GT; getDoctrine() - &GT; getRepository(车::类) - &GT; findByUserId($用户); 
   
 
  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dqgg25493 2018-04-25 18:00
    已采纳

    There is an example of how to do what you're looking to achieve in the Symfony Documentation on How to Embed a Collection of Forms.

    For your specific use case, you will want to create a UserCartsForm and a Separate CartsForm.

    In your UserCart add the carts field as a CollectionType. Symfony will then process the field as a series of forms.

    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,
            ]);
        }
    }
    

    Add the fields you want editable on your form to the 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,
            ]);
        }
    }
    

    In your controller, reference the user entity as your UserCartsForm data.

    src/AppBundle/Controller/DefaultController.php

    namespace AppBundle\Controller;
    
    use AppBundle\Form\UserCartsForm;
    
    class DefaultController extends Controller
    {
    
       /**
        * @Route('/{id}/user-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($carts);
             return $this->redirectToRoute('some_route');
          }
    
          return $this->render('user_carts_form.html.twig', [
              'form' => $form
          ]);
       }
    }
    

    Then you should be able to easily retrieve the data from your twig template to render as you would like.

    app/Resources/views/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) %}
    

    Update for Entity Constraints

    By default Symfony will use all constraints (Default) assigned to the entity when validating your form causing $form->isValid() to return false.

    https://symfony.com/doc/3.4/validation/groups.html

    If no groups are specified, all constraints that belong to the group Default will be applied.

    To resolve the issue, use Validation Groups to separate the entity constraints and declare the desired groups on their respective form(s).

    Example:

    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;
    
        //...
    }
    

    Then to use your validation group(s) on the desired form, in this case RegistrationForm, you declare the desired group in the AbstractTye::configureOptions as one of the 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']
             ]);
         }
    
    }
    

    Now the User::NotBlank constraint will only apply for the RegistrationForm::isValid() or any other form that declare the registration validation group.

    已采纳该答案
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题