手动提交 Symfony 表单后 CollectionType 字段显示为空

CollectionType field showing empty after manually submitting Symfony Form

我有一对多关系

图书 <----* BookImage

图书:

oneToMany:
      bookImages:
            targetEntity: BookImage
            mappedBy: book
            cascade: [persist,remove]

BookImage:

manyToOne:
       book:
            targetEntity: Book
            inversedBy: bookImages
            joinColumn:
              name: book_id
              referencedColumnName: id

所以我的表单有一个 collectionType 字段。

图书类型:

$builder->add('bookImages', 'collection', array(
                'type'         => new BookImageType(),
                'allow_add'    => true,
//                'allow_delete'    => true,
                'by_reference' =>false

            ));

BookImageType:

$builder->add('imageName','text',array(
            'constraints' => array(
                new NotBlank(),

            )
        ));
        $builder->add('imageUrl','text',array(
            'constraints' => array(
                new NotBlank(),

            )
        ));

控制器通过Ajax调用保存数据:

public function addNewSellBookAction(Request $request)
{

    $serializer = $this->container->get('jms_serializer');
    $userId = $this->get('security.token_storage')->getToken()->getUser()->getId();
    $em = $this->getDoctrine()->getManager();

    $content = $request->get('book');
    $bookData = json_decode($content, true);

    $book = new Book();


    $bookImage1 = new BookImage();
    $bookImage1->setImageName("Amazon Book Image");
    $bookImage1->setImageUrl("http://url1.com");

    $book->addBookImage($bookImage1);

    $bookImage2 = new BookImage();
    $bookImage2->setImageName("Amazon Book Image");
    $bookImage2->setImageUrl("http://url1.com");

    $book->addBookImage($bookImage2);



    $bookData['bookSeller']=$userId;



    $bookForm = $this->createForm(new BookType(), $book);


    var_dump($bookForm->getData()->getBookImages()); //Image Data Before Submit 
    $bookForm->submit($bookData);
    var_dump($bookForm->getData()->getBookImages()); //Image Data After Submit

    if($bookForm->isValid()){
        $em->persist($book);
        $em->flush();
        return $this->createJsonResponse('success',array('successTitle'=>"Book Successfully added to sell List"));
    }else{
        $error= $serializer->serialize($bookForm,'json');
        return new Response($error,200);
    }



}

现在提交前后的 BookImage 数据为:

object(Doctrine\Common\Collections\ArrayCollection)[580]
  private 'elements' => 
    array (size=2)
      0 => 
        object(AppBundle\Entity\BookImage)[581]
          protected 'id' => null
          private 'imageName' => string 'Amazon Book Image' (length=17)
          private 'imageUrl' => string 'http://url1.com' (length=15)
          private 'titleImage' => null
          private 'book' => 
            object(AppBundle\Entity\Book)[578]
              ...
      1 => 
        object(AppBundle\Entity\BookImage)[582]
          protected 'id' => null
          private 'imageName' => string 'Amazon Book Image' (length=17)
          private 'imageUrl' => string 'http://url1.com' (length=15)
          private 'titleImage' => null
          private 'book' => 
            object(AppBundle\Entity\Book)[578]
              ...
object(Doctrine\Common\Collections\ArrayCollection)[580]
  private 'elements' => 
    array (size=2)
      0 => 
        object(AppBundle\Entity\BookImage)[581]
          protected 'id' => null
          private 'imageName' => null
          private 'imageUrl' => null
          private 'titleImage' => boolean false
          private 'book' => 
            object(AppBundle\Entity\Book)[578]
              ...
      1 => 
        object(AppBundle\Entity\BookImage)[582]
          protected 'id' => null
          private 'imageName' => null
          private 'imageUrl' => null
          private 'titleImage' => boolean false
          private 'book' => 
            object(AppBundle\Entity\Book)[578]

为什么提交数据后collectionType字段值为null或为空?尽管其他字段具有完美的价值。谁能解释一下?还是我的结构有问题?提前致谢。

图书实体

class Book
{
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->messages = new ArrayCollection();
        $this->bookImages = new ArrayCollection();
    }

    /**
     * @var integer
     *
     */
    protected $id;

    /**
     * @var string
     *
     */
    private $bookTitle;

    /**
     * @var string
     *
     */
    private $bookDirectorAuthorArtist;

    /**
     * @var string
     *
     */
    private $bookEdition;

    /**
     * @var string
     *
     */
    private $bookIsbn10;

    /**
     * @var string
     *
     */
    private $bookIsbn13;

    /**
     * @var string
     *
     */
    private $bookPublisher;

    /**
     * @var date
     *
     */
    private $bookPublishDate;


    /**
     * @var string
     *
     */
    private $bookBinding;

    /**
     * @var string
     *
     */
    private $bookPage;

    /**
     * @var string
     *
     */
    private $bookPriceSell;

    /**
     * @var string
     *
     */
    private $bookLanguage;

    /**
     * @var text
     *
     */
    private $bookDescription;

    /**
     * @var string
     *
     */
    private $bookCondition;

    /**
     * @var string
     *
     */
    private $bookIsHighlighted;

    /**
     * @var string
     *
     */
    private $bookHasNotes;

    /**
     * @var string
     *
     */
    private $bookComment;

    /**
     * @var string
     *
     */
    private $bookContactMethod;

    /**
     * @var string
     *
     */
    private $bookContactHomeNumber;

    /**
     * @var string
     *
     */
    private $bookContactCellNumber;
    /**
     * @var string
     *
     */
    private $bookContactEmail;
    /**
     * @var string
     *
     */
    private $bookIsAvailablePublic;

    /**
     * @var boolean
     *
     */
    private $bookPaymentMethodCaShOnExchange;
    /**
     * @var boolean
     *
     */
    private $bookPaymentMethodCheque;
    /**
     * @var date
     *
     */
    private $bookAvailableDate;




    private $bookImages;

    private $bookBuyer;

    private $bookSeller;

    private $messages;





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

    /**
     * Set bookTitle
     *
     * @param string $bookTitle
     * @return Book
     */
    public function setBookTitle($bookTitle)
    {
        $this->bookTitle = $bookTitle;

        return $this;
    }

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

    /**
     * Set bookDirectorAuthorArtist
     *
     * @param string $bookDirectorAuthorArtist
     * @return Book
     */
    public function setBookDirectorAuthorArtist($bookDirectorAuthorArtist)
    {
        $this->bookDirectorAuthorArtist = $bookDirectorAuthorArtist;

        return $this;
    }

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

    /**
     * Set bookEdition
     *
     * @param string $bookEdition
     * @return Book
     */
    public function setBookEdition($bookEdition)
    {
        $this->bookEdition = $bookEdition;

        return $this;
    }

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

    /**
     * Set bookIsbn10
     *
     * @param string $bookIsbn10
     * @return Book
     */
    public function setBookIsbn10($bookIsbn10)
    {
        $this->bookIsbn10 = $bookIsbn10;

        return $this;
    }

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

    /**
     * Set bookIsbn13
     *
     * @param string $bookIsbn13
     * @return Book
     */
    public function setBookIsbn13($bookIsbn13)
    {
        $this->bookIsbn13 = $bookIsbn13;

        return $this;
    }

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

    /**
     * Set bookPublisher
     *
     * @param string $bookPublisher
     * @return Book
     */
    public function setBookPublisher($bookPublisher)
    {
        $this->bookPublisher = $bookPublisher;

        return $this;
    }

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

    /**
     * Set bookPublishDate
     *
     * @param \DateTime $bookPublishDate
     * @return Book
     */
    public function setBookPublishDate($bookPublishDate)
    {
        $this->bookPublishDate = $bookPublishDate;

        return $this;
    }

    /**
     * Get bookPublishDate
     *
     * @return \DateTime 
     */
    public function getBookPublishDate()
    {
        return $this->bookPublishDate;
    }

    /**
     * Set bookBinding
     *
     * @param string $bookBinding
     * @return Book
     */
    public function setBookBinding($bookBinding)
    {
        $this->bookBinding = $bookBinding;

        return $this;
    }

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

    /**
     * Set bookPage
     *
     * @param string $bookPage
     * @return Book
     */
    public function setBookPage($bookPage)
    {
        $this->bookPage = $bookPage;

        return $this;
    }

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



    /**
     * Set bookLanguage
     *
     * @param string $bookLanguage
     * @return Book
     */
    public function setBookLanguage($bookLanguage)
    {
        $this->bookLanguage = $bookLanguage;

        return $this;
    }

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

    /**
     * Add messages
     *
     * @param \AppBundle\Entity\Message $messages
     * @return Book
     */
    public function addMessage(\AppBundle\Entity\Message $messages)
    {
        $this->messages[] = $messages;

        return $this;
    }

    /**
     * Remove messages
     *
     * @param \AppBundle\Entity\Message $messages
     */
    public function removeMessage(\AppBundle\Entity\Message $messages)
    {
        $this->messages->removeElement($messages);
    }

    /**
     * Get messages
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getMessages()
    {
        return $this->messages;
    }

    /**
     * Set bookBuyer
     *
     * @param \AppBundle\Entity\User $bookBuyer
     * @return Book
     */
    public function setBookBuyer(\AppBundle\Entity\User $bookBuyer = null)
    {
        $this->bookBuyer = $bookBuyer;

        return $this;
    }

    /**
     * Get bookBuyer
     *
     * @return \AppBundle\Entity\User 
     */
    public function getBookBuyer()
    {
        return $this->bookBuyer;
    }

    /**
     * Set bookSeller
     *
     * @param \AppBundle\Entity\User $bookSeller
     * @return Book
     */
    public function setBookSeller(\AppBundle\Entity\User $bookSeller = null)
    {
        $this->bookSeller = $bookSeller;

        return $this;
    }

    /**
     * Get bookSeller
     *
     * @return \AppBundle\Entity\User 
     */
    public function getBookSeller()
    {
        return $this->bookSeller;
    }

    /**
     * Set bookPriceSell
     *
     * @param string $bookPriceSell
     * @return Book
     */
    public function setBookPriceSell($bookPriceSell)
    {
        $this->bookPriceSell = $bookPriceSell;

        return $this;
    }

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

    /**
     * Set bookDescription
     *
     * @param string $bookDescription
     * @return Book
     */
    public function setBookDescription($bookDescription)
    {
        $this->bookDescription = $bookDescription;

        return $this;
    }

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

    /**
     * Set bookCondition
     *
     * @param string $bookCondition
     * @return Book
     */
    public function setBookCondition($bookCondition)
    {
        $this->bookCondition = $bookCondition;

        return $this;
    }

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

    /**
     * Set bookIsHighlighted
     *
     * @param string $bookIsHighlighted
     * @return Book
     */
    public function setBookIsHighlighted($bookIsHighlighted)
    {
        $this->bookIsHighlighted = $bookIsHighlighted;

        return $this;
    }

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

    /**
     * Set bookHasNotes
     *
     * @param string $bookHasNotes
     * @return Book
     */
    public function setBookHasNotes($bookHasNotes)
    {
        $this->bookHasNotes = $bookHasNotes;

        return $this;
    }

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

    /**
     * Set bookComment
     *
     * @param string $bookComment
     * @return Book
     */
    public function setBookComment($bookComment)
    {
        $this->bookComment = $bookComment;

        return $this;
    }

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

    /**
     * Set bookContactMethod
     *
     * @param string $bookContactMethod
     * @return Book
     */
    public function setBookContactMethod($bookContactMethod)
    {
        $this->bookContactMethod = $bookContactMethod;

        return $this;
    }

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

    /**
     * Set bookContactHomeNumber
     *
     * @param string $bookContactHomeNumber
     * @return Book
     */
    public function setBookContactHomeNumber($bookContactHomeNumber)
    {
        $this->bookContactHomeNumber = $bookContactHomeNumber;

        return $this;
    }

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

    /**
     * Set bookContactCellNumber
     *
     * @param string $bookContactCellNumber
     * @return Book
     */
    public function setBookContactCellNumber($bookContactCellNumber)
    {
        $this->bookContactCellNumber = $bookContactCellNumber;

        return $this;
    }

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

    /**
     * Set bookContactEmail
     *
     * @param string $bookContactEmail
     * @return Book
     */
    public function setBookContactEmail($bookContactEmail)
    {
        $this->bookContactEmail = $bookContactEmail;

        return $this;
    }

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

    /**
     * Set bookIsAvailablePublic
     *
     * @param string $bookIsAvailablePublic
     * @return Book
     */
    public function setBookIsAvailablePublic($bookIsAvailablePublic)
    {
        $this->bookIsAvailablePublic = $bookIsAvailablePublic;

        return $this;
    }

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

    /**
     * Set bookPaymentMethodCaShOnExchange
     *
     * @param string $bookPaymentMethodCaShOnExchange
     * @return Book
     */
    public function setBookPaymentMethodCaShOnExchange($bookPaymentMethodCaShOnExchange)
    {
        $this->bookPaymentMethodCaShOnExchange = $bookPaymentMethodCaShOnExchange;

        return $this;
    }

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

    /**
     * Set bookPaymentMethodCheck
     *
     * @param string $bookPaymentMethodCheck
     * @return Book
     */
    public function setBookPaymentMethodCheck($bookPaymentMethodCheck)
    {
        $this->bookPaymentMethodCheck = $bookPaymentMethodCheck;

        return $this;
    }

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

    /**
     * Add bookImages
     *
     * @param \AppBundle\Entity\BookImage $bookImages
     * @return Book
     */
    public function addBookImage(\AppBundle\Entity\BookImage $bookImages)
    {
        $this->bookImages->add($bookImages);
        $bookImages->setBook($this);
        return $this;
    }

    /**
     * Remove bookImages
     *
     * @param \AppBundle\Entity\BookImage $bookImages
     */
    public function removeBookImage(\AppBundle\Entity\BookImage $bookImages)
    {
        $this->bookImages->removeElement($bookImages);
    }

    /**
     * Get bookImages
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getBookImages()
    {
        return $this->bookImages;
    }

    /**
     * Set bookPaymentMethodCheque
     *
     * @param boolean $bookPaymentMethodCheque
     * @return Book
     */
    public function setBookPaymentMethodCheque($bookPaymentMethodCheque)
    {
        $this->bookPaymentMethodCheque = $bookPaymentMethodCheque;

        return $this;
    }

    /**
     * Get bookPaymentMethodCheque
     *
     * @return boolean 
     */
    public function getBookPaymentMethodCheque()
    {
        return $this->bookPaymentMethodCheque;
    }

    /**
     * Set bookAvailableDate
     *
     * @param \DateTime $bookAvailableDate
     * @return Book
     */
    public function setBookAvailableDate($bookAvailableDate)
    {
        $this->bookAvailableDate = $bookAvailableDate;

        return $this;
    }

    /**
     * Get bookAvailableDate
     *
     * @return \DateTime 
     */
    public function getBookAvailableDate()
    {
        return $this->bookAvailableDate;

    }

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


}

BookImage 实体

class BookImage
{


    /**
     * @var integer
     *
     */
    protected $id;

    /**
     * @var string
     *
     */
    private $imageName;

    /**
     * @var string
     *
     */
    private $imageUrl;

    /**
     * @var boolean
     *
     */
    private $titleImage;


    private $book;


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

    /**
     * Set imageName
     *
     * @param string $imageName
     * @return BookImage
     */
    public function setImageName($imageName)
    {
        $this->imageName = $imageName;

        return $this;
    }

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

    /**
     * Set imageUrl
     *
     * @param string $imageUrl
     * @return BookImage
     */
    public function setImageUrl($imageUrl)
    {
        $this->imageUrl = $imageUrl;

        return $this;
    }

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

    /**
     * Set titleImage
     *
     * @param boolean $titleImage
     * @return BookImage
     */
    public function setTitleImage($titleImage)
    {
        $this->titleImage = $titleImage;

        return $this;
    }

    /**
     * Get titleImage
     *
     * @return boolean 
     */
    public function getTitleImage()
    {
        return $this->titleImage;
    }

    /**
     * Set book
     *
     * @param \AppBundle\Entity\Book $book
     * @return BookImage
     */
    public function setBook(\AppBundle\Entity\Book $book = null)
    {
        $this->book = $book;

        return $this;
    }

    /**
     * Get book
     *
     * @return \AppBundle\Entity\Book 
     */
    public function getBook()
    {
        return $this->book;
    }
    public function __toString()
    {
        return strval($this->id);
    }
}

我不确定。根据 symfony documentation

检查任务控制器行号 20 和 23

 $task->getTags()->add($tag2);

标签集合可以通过 $task->getTags() 自然访问,并且可以持久保存到数据库中或根据需要使用。

我觉得你漏掉了什么

$book->addBookImage($bookImage1);

试试这个

$book->getBookImages()->add($bookImage1);

我一直在寻找答案近 7 天,终于想出了一个解决方案。但不知道这是否是一种不好的做法。

只需将数据作为 array 放入 submitData。提交后,该值将通过表单添加到该特定实体。

public function addNewSellBookAction(Request $request)
    {
        $em = $this->getDoctrine()->getManager();
        $serializer = $this->container->get('jms_serializer');
        $userId = $this->get('security.token_storage')->getToken()->getUser()->getId();


        $content = $request->get('book');
        $bookData = json_decode($content, true);

        $bookData['bookImages']=array();

        array_push($bookData['bookImages'],array(
            'imageName'=>"Amazon Book Image",
            'imageUrl'=>"http://url1.com"
        ));
        array_push($bookData['bookImages'],array(
            'imageName'=>"Amazon Book Image",
            'imageUrl'=>"http://url1.com"
        ));

        $bookData['bookSeller']=$userId;


        $book = new Book();
        $bookForm = $this->createForm(new BookType(),$book);


        var_dump($bookForm->getData()->getBookImages());
        $bookForm->submit($bookData);
        var_dump($book->getBookImages());

        if($bookForm->isValid()){
            $em->persist($book);
            $em->flush();
            return $this->createJsonResponse('success',array('successTitle'=>"Book Successfully added to sell List"));
        }else{
            $error= $serializer->serialize($bookForm,'json');
            return new Response($error,200);
        }

    }

希望对大家有所帮助。

赏金仍然开放如果有人提供最佳实践的答案

如果您不需要使用请求数据修改图像,请在提交表单后添加新图像。

$bookForm->submit($bookData);
// ...
$book->addBookImage($bookImage1);