簡體   English   中英

Symfony-形式-多對多關系-集合類型

[英]Symfony - form - many to many relation - collection type

情況如下:

我有實體財產

class Property
{
    /**
     * @ORM\Id
     * @ORM\Column(type="string")
     * @ORM\GeneratedValue(strategy="UUID")
     */
    protected $id;

    /**
     * @ORM\ManyToMany(targetEntity="PropertyEquipment", inversedBy="properties")
     */
    protected $propertyEquipments;

    public function __construct()
    {
        $this->propertyEquipments = new ArrayCollection();
    }

    public function getId()
    {
        return $this->id;
    }

    public function addPropertyEquipment(\AppBundle\Entity\PropertyEquipment $propertyEquipment)
    {
        $this->propertyEquipments[] = $propertyEquipment;

        return $this;
    }

    public function removePropertyEquipment(\AppBundle\Entity\PropertyEquipment $propertyEquipment)
    {
        $this->propertyEquipments->removeElement($propertyEquipment);
    }

    public function getPropertyEquipments()
    {
        return $this->propertyEquipments;
    }
}

和實體PropertyEquipment:

class PropertyEquipment
{

    /**
     * @ORM\Id
     * @ORM\Column(type="string")
     * @ORM\GeneratedValue(strategy="UUID")
     */
    protected $id;

    /**
     * @ORM\ManyToMany(targetEntity="Property", mappedBy="propertyEquipments")
     */
    protected $properties;

    /**
     * @ORM\Column(type="string", length=100)
     * @Gedmo\Translatable
     */
    protected $equipmentName;


    public function __construct()
    {
        $this->properties = new ArrayCollection();
    }

    /**
     * Get id
     *
     * @return string
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return mixed
     */
    public function getEquipmentName()
    {
        return $this->equipmentName;
    }

    /**
     * @param mixed $equipmentName
     */
    public function setEquipmentName($equipmentName)
    {
        $this->equipmentName = $equipmentName;
    }

    public function addProperty(Property $property)
    {
        $this->properties[] = $property;

        return $this;
    }

    public function removeProperty(Property $property)
    {
        $this->properties->removeElement($property);
    }

    public function getProperties()
    {
        return $this->properties;
    }
}

表格PropertyCreation

class PropertyCreation extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            //with this I see the values coming from DB in the template
            ->add("propertyEquipments", PropertyEquipmentCreation::class)

            //with this it's empty :/
            /*->add("propertyEquipments", CollectionType::class, array(
                "entry_type" => PropertyEquipmentCreation::class,
            ))*/
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Property::class
        ));
    }
}

這是PropertyEquipmentCreation的形式:

class PropertyEquipmentCreation extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder      
            ->add('propertyEquipment', EntityType::class, [
                'class' => 'AppBundle\Entity\PropertyEquipment',
                'choice_label' => 'equipmentName',
                'expanded' => true,
                'multiple' => true
            ]);
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => PropertyEquipment::class,
        ]);
    }
}

和控制器

public function createPropertyAction(Request $request)
{
    $property = new Property();

    $form = $this->createForm(PropertyCreation::class, $property);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $entityManager = $this->getDoctrine()->getManager();
        $entityManager->persist($property);
        $entityManager->flush();

        return $this->redirectToRoute('homepage');
    }
    return $this->render('form/owner_create_property.html.twig', ["form" => $form->createView()]);
}

我的錯誤:

Expected value of type "Doctrine\\Common\\Collections\\Collection|array" for association field "AppBundle\\Entity\\Property#$propertyEquipments", got "Doctrine\\Common\\Collections\\ArrayCollection" instead.

我是否必須使用諸如class PropertyEquipmentTransformer implements DataTransformerInterface東西進行轉換?

我認為您應該在PropertyEquipmentCreation使用getParent()函數並從EntityType::class繼承,然后將所有字段配置放入configureOptions()函數中(刪除buildForm函數),它應該可以工作。

您遇到了這個問題,因為它是實現中的compound form ,沒有simple form ,symfony無法解決需要將子表單內部創建的哪個字段用作實體字段的源

首先!

非常感謝Nickolaus!

這是解決方案(PropertyEquipmentCreation):

namespace AppBundle\Form\Type;

use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;


class PropertyEquipmentCreation extends AbstractType
{

/**
 * @param OptionsResolver $resolver
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'class' => 'AppBundle\Entity\PropertyEquipment',
        'choice_label' => 'equipmentName',
        'expanded' => true,
        'multiple' => true,
    ]);
}

public function getParent()
{
    return EntityType::class;
}
}

對於(PropertyCreation)

<?php


namespace AppBundle\Form;


use AppBundle\Form\Type\PropertyEquipmentCreation;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PropertyCreation extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('description', TextareaType::class)
        ->add('name', TextType::class)
        ->add("propertyEquipments", PropertyEquipmentCreation::class)
        ->add('save', SubmitType::class);
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => Property::class
    ));
}
}

非常感謝 !

嘗試使用Doctrine ArrayCollection而不是ArrayCollections:

$this->propertyEquipments = new \Doctrine\Common\Collections\ArrayCollection();

這應該工作!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM