簡體   English   中英

Symfony:嵌入ManyToOne-OneToMany關系的表單集合

[英]Symfony: Embed collection of forms for ManyToOne-OneToMany relation

我正在使用Doctrine運行Symfony 2.3以及這三個(相關)實體: PublicationAuthorAuthorPublication 作者出版物都與AuthorPublication有多對一的關系(因此它基本上是作者出版物之間的多對多關系,但我需要AuthorPublication實體來訂購出版物的作者)

我希望有一個表單,用戶可以創建一個新的出版物,並根據需要為該出版物選擇盡可能多的作者。

我研究了這篇文章: 如何嵌入表單集合但我不明白如何將其應用於我的問題,因為AuthorPublication實體介於兩者之間。

相關守則:

出版物

<?php

namespace ind\PubBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="ind\PubBundle\Repository\PublicationRepository")
 * @ORM\Table("publications")
 */
class Publication {

    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $pid;

    /**
     * @ORM\OneToMany(targetEntity="AuthorPublication", mappedBy="publication")
     * @ORM\OrderBy({"order_id" = "ASC"})
     */
    protected $publicationAuthors;


//some more attributes + getters/seters
?>

作者

<?php

namespace ind\PubBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table("aid_author")
 */
class Author {

    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $aid;

    /**
     * @ORM\Column(type="string", length=255)
     */
    protected $author_surname;

    /**
     * @ORM\Column(type="string", length=255)
     */
    protected $author_forename;

    /**
     * @ORM\OneToMany(targetEntity="AuthorPublication", mappedBy="author")
     */
    protected $authorPublication;
?>

AuthorPublication

<?php

namespace ind\PubBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table("aid_pid")
 */
class AuthorPublication {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     */
    protected $aid;

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     */
    protected $pid;

    /**
     * @ORM\Column(type="integer")
     */
    protected $order_id;

    /**
     * @ORM\ManyToOne(targetEntity="Publication", inversedBy="publicationAuthors")
     * @ORM\JoinColumn(name="pid", referencedColumnName="pid")
     */
    protected $publication;

    /**
     * @ORM\ManyToOne(targetEntity="Author", inversedBy="authorPublication")
     * @ORM\JoinColumn(name="aid", referencedColumnName="aid")
     */
    protected $author;
?>
  1. 您必須制作AuthorPublicationType表單。 您將字段作者作為“實體”和您的其他字段...

  2. 您使您的PublicationType包括AuthorPublication( 嵌入表單 )。

  3. 然后你可以添加新的AuthorPublication與原型和非常簡單的JavaScript。

  4. 請注意,當您必須首先使用authorPublication attribut保存您的實體Publication時。 並且在更新發布之后,例如使用Publication和LifecycleCallbacks中的臨時ArrayCollection定義authorPublication。

編輯:示例。

我的實體是Sport OneToMany SportParam ManyToOne ConfigParam。 SportParam由Sport,ConfigParam和值組成。

我想用多個ConfigParam創建一個新的Sport:

  1. SportParamType:

     public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('ConfigParam', 'entity', array( 'class' => 'PPHBSportScoringBundle:ConfigParam', 'property' => 'nom', 'multiple' => false, 'label'=>'Paramètre' )) ->add('valeur','number',array('precision'=>2)) ; } 
  2. SportType

     public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('nom') ->add('SportParams', 'collection', array( 'type'=> new SportParamType(), 'allow_add' => true, 'allow_delete' => true, 'by_reference'=> false )) ; } 
  3. 我的form.html.twig:

     {{ form_start(form) }} {{ form_errors(form) }} {{ form_row(form.nom) }} <ul class=SportParams data-prototype="{{ form_widget(form.SportParams.vars.prototype)|e }}"> {% for param in form.SportParams %} <li> {{ form_errors(param.ConfigParam) }} {{ form_widget(param.ConfigParam) }} {{ form_errors(param.valeur) }} {{ form_widget(param.valeur) }} </li> {% endfor %} </ul> <input type="submit" class="btn btn-primary" /> {{ form_end(form) }} 

    我的Javascript精煉,因為它包含更多的代碼(AJAX調用)。 它可能包含一些錯誤。 如果不清楚請查看文檔

     <script type="text/javascript"> var $container = $('ul.SportParams'); // button to add a new SportParam var $addSportParamLink = $('<a href="#" id="ajout_param" class="btn btn-primary btn-xs">Ajouter un paramètre</a>'); var $newLinkLi = $('<li></li>').append($addSportParamLink); $(document).ready(function() { //delete button on each existing SportParam $container.find('li').each(function() { addParamFormDeleteLink($(this)); }); //add button $container.append($newLinkLi); // adding a new form when cliking Add button $addSportParamLink.on('click',function(e) { e.preventDefault(); // évite qu'un #apparaisse dans l'URL var index = $container.children().length-1; addParamForm($container,$newLinkLi); var bAffiche; return false; }); // adding a new form SportParam function addParamForm($container, $newLinkLi) { var $prototype = $container.attr('data-prototype'); var newForm = $prototype.replace(/__name__/g, $container.children().length-1); var $newFormLi = $('<li></li>').append(newForm); $newLinkLi.before($newFormLi); addParamFormDeleteLink($newFormLi); } function addParamFormDeleteLink($paramFormLi){ var $removeFormA = $('<a href="#" class="btn btn-danger btn-xs">Supprimer</a>'); $paramFormLi.append($removeFormA); $removeFormA.on('click', function(e) { e.preventDefault(); $paramFormLi.remove(); }); } }); </script> 
  4. 體育實體致電回來:

     /** * sport * * @ORM\\Table() * @ORM\\Entity * @ORM\\HasLifecycleCallbacks * @ORM\\Entity(repositoryClass="SportRepository") */ class Sport { ...Entity attribut... /** * @var ArrayCollection * * To save Sport without SportParams */ private $SportParamsTMP; ...getter and setter ... /** * @ORM\\PrePersist */ public function saveSportParams() { $this->SportParamsTMP = $this->SportParams; $this->SportParams = null; } /** * @ORM\\PostPersist */ public function restoreSportParams() { if ($this->SportParamsTMP == !null) { $this->SportParams = $this->SportParamsTMP; } $this->SportParamsTMP = null; } } 

    最后控制器的功能是添加一個新的Sport:

     public function addAction() { $sport = new Sport(); $form = $this->createForm(new SportType(), $sport); $request = $this->getRequest(); if ($request->getMethod() == "POST") { $form->bind($request); if($form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($sport); //saving sport without parameter $em->flush(); //updating sport with parameter $em->flush(); return $this->redirect($this->generateUrl('pphb_sport_liste')); } } return $this->render('PPHBSportScoringBundle:Championnat/Sport:add.html.twig', array( 'form' => $form->createView(), )); } 

我希望它有所幫助。
不知道這是否是最好的方法,但它對我有用。 如果要改進的地方請告訴我。

暫無
暫無

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

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