简体   繁体   English

表单Symfony2中的依赖关系

[英]Dependencies in forms Symfony2

I'm working on a webapplication in Symfony2. 我正在研究Symfony2中的Web应用程序。 I came to a point in which I need some advice/explanation from some one more advanced in Symfony. 在某些方面,我需要一些Symfony中更先进的建议/解释。

I have a part of my database that is set up as follows: 我的数据库的一部分设置如下:

I have cards that belong to a card attribute set and consists of card values. 我有属于卡属性集的卡,由卡值组成。

I have card attribute sets that have many attributes, a card attribute can belong to many card attribute sets (obviously a many to many relationship). 我有卡属性集有很多属性,卡属性可以属于许多卡属性集(显然是多对多的关系)。

Then depending on the card attribute the attribute has an attribute value, for example a text has a value_text of type varchar and a boolean has a value_boolean of type boolean. 然后,根据card属性,该属性具有属性值,例如,text具有varchar类型的value_text,boolean具有boolean类型的value_boolean。

You can imagine when making a form to create a new card, the form needs to generate input fields depending on the card attribute set it belongs to and depending on the attributes that belong to the attribute set right? 您可以想象在制作表单时创建新卡片时,表单需要根据其所属的卡片属性集生成输入字段,并根据属于该属性集的属性生成吗?

So here's my question; 所以这是我的问题; is there a way to dynamically generate input fields in a form depending the entity chosen by the user. 有没有办法根据用户选择的实体动态生成表单中的输入字段。 I've read about events but I'm not sure that they satisfy my needs. 我读过有关活动但我不确定它们是否满足我的需求。

This is the code for my entities (I removed to Getters and Setters for a more simple view): 这是我的实体的代码(我删除了Getters和Setters以获得更简单的视图):

Card: 卡:

/**
 * card
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="clientsBundle\Entity\cardRepository")
 * @UniqueEntity(
 *      fields={"cardLabel"},
 *      message="A card with this label already exists"
 * )
 */
class card
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="card_label", type="string", length=999)
     */
    private $cardLabel;

    /**
     * @ORM\ManyToOne(targetEntity="project", inversedBy="project_cards")
     * @ORM\JoinColumn(name="project_id", referencedColumnName="id", onDelete = "SET NULL")
     */
    protected $card_project;

     /**
     * @ORM\ManyToOne(targetEntity="cardAttributeSet", inversedBy="cas_cards")
     * @ORM\JoinColumn(name="cas_id", referencedColumnName="id")
     **/
    protected $cardAttrSet;

    /**
     * @ORM\OneToMany(targetEntity="cardAttrValue", mappedBy="card", cascade={"persist"}, orphanRemoval=true)
     **/
    protected $card_values;

    /**
    * @ORM\ManyToMany(targetEntity="user", mappedBy="cards")
    */
    private $users;

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

Card Attribute: 卡属性:

 /**
 * cardAttribute
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="clientsBundle\Entity\cardAttributeRepository")
 * @UniqueEntity(
 *      fields={"name"},
 *      message="An attribute with this name already exists"
 * )
 */
class cardAttribute
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
     * @var string
     *
     * @ORM\Column(name="type", type="string", length=255)
     */
    private $type;
}

Card Attribute Set 卡属性集

 /**
 * cardAttributeSet
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="clientsBundle\Entity\cardAttributeSetRepository")
 * @UniqueEntity(
 *      fields={"casLabel"},
 *      message="An attribute set with this label already exists"
 * )
 */
class cardAttributeSet
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public $id;

    /**
     * @var string
     *
     * @ORM\Column(name="cas_label", type="string", length=255)
     */
    private $casLabel;

    /**
     * @ORM\OneToMany(targetEntity="card", mappedBy="cardAttrSet")
     */
    private $cas_cards;

    /**
     * @ORM\ManyToMany(targetEntity="cardAttribute")
     * @ORM\JoinTable(name="cas_attribute",
     *          joinColumns={@ORM\JoinColumn(name="cas_id", referencedColumnName="id")},
     *          inverseJoinColumns={@ORM\JoinColumn(name="attribute_id", referencedColumnName="id")}  
     *          )
     */
    private $attributes;

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

Card Attribute Value 卡属性值

 /**
 * cardAttrValue
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="clientsBundle\Entity\cardAttrValueRepository")
 * @UniqueEntity(
 *      fields={"valueText"}
 * )
 */
class cardAttrValue
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="value_text", type="string", length=255, nullable=true)
     */
    private $valueText;

    /**
     * @var string
     *
     * @ORM\Column(name="value_varchar", type="string", length=255, nullable=true)
     */
    private $valueVarchar;

    /**
     * @var integer
     *
     * @ORM\Column(name="value_int", type="integer", nullable=true, nullable=true)
     */
    private $valueInt;

    /**
     * @var boolean
     *
     * @ORM\Column(name="value_boolean", type="boolean", nullable=true, nullable=true)
     */
    private $valueBoolean;

    /**
     * @ORM\ManyToOne(targetEntity="card", inversedBy="card_values")
     * @ORM\JoinColumn(name="card_id", referencedColumnName="id")
     **/
    private $card;

    /**
     * @ORM\ManyToOne(targetEntity="cardAttribute")
     * @ORM\JoinColumn(name="cardAttributes_id", referencedColumnName="id")
     **/
    private $cardAttribute;
}

Create a form type CardAttributeValueType for CardAttributeValue entity, inside this form add fields depending on passed attribute type: CardAttributeValue实体创建表单类型CardAttributeValueType ,在此表单中根据传递的属性类型添加字段:

class CardAttributeValueType extends AbstractType

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) {
        $value = $event->getData();
        $form = $event->getForm();

        if (!$value) {
            return;
        }

        switch ($value->getCardAttribute()->getType()) {
            case 'text':
                $form->add('valueVarchar', 'text');
                break;

            // Same for other attribute types
        }
     }
}

Then, add collection field type for card_values inside CardType form type and pass CardAttributeValueType as collection item type. 然后,在CardType表单类型中添加card_values collection字段类型,并将CardAttributeValueType作为集合项类型传递。

In the Card entity edit getCardValues() method so it will return every attribute from CardAttributeSet , not only ones for which value entities exist. Card实体中编辑getCardValues()方法,因此它将返回CardAttributeSet每个属性,而不仅仅是存在值实体的属性。

UPDATE UPDATE

public function getCardValues()
{
    $collection = new ArrayCollection();

    if (!$this->cardAttrSet) {
        return $collection;
    }

    // Add existing values
    foreach ($this->card_values as $value) {
        $collection[$value->getCardAttribute()->getId()] = $value;
    }

    // Get all attributes from the set and create values for missing attributes
    foreach ($this->cardAttrSet->getAttributes() as $attr) {
        if (!isset($collection[$attr->getId()])) {
            $value = new cardAttrValue();
            $value->setCardAttribute($attr);

            $collection[$attr->getId()] = $value;
        }
    }

    return $collection;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM