表单中的依赖关系Symfony2

时间:2015-06-18 09:25:32

标签: php forms symfony events entities

我正在研究Symfony2中的Web应用程序。我找到了一些我需要一些Symfony更高级的建议/解释。

我的数据库的一部分设置如下:

我的卡属于卡片属性集,由卡片值组成。

我的卡属性集有很多属性,卡属性可以属于很多卡属性集(显然是多对多的关系)。

然后,根据card属性,该属性具有属性值,例如,text具有varchar类型的value_text,boolean具有boolean类型的value_boolean。

您可以想象在制作表单时创建新卡片时,表单需要根据其所属的卡片属性集生成输入字段,并根据属于该属性集的属性生成吗?

所以这是我的问题;有没有办法根据用户选择的实体动态生成表单中的输入字段。我读过有关事件但我不确定它们是否满足我的需求。

这是我的实体的代码(我删除了Getters和Setters以获得更简单的视图):

卡:

/**
 * 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();
    }
}

卡片属性:

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

卡片属性设置

 /**
 * 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();
    }
}

卡片属性值

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

1 个答案:

答案 0 :(得分:3)

CardAttributeValueType实体创建表单类型CardAttributeValue,在此表单中根据传递的属性类型添加字段:

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

然后,在collection表单类型中添加card_values的{​​{1}}字段类型,并将CardType作为集合项类型传递。

CardAttributeValueType实体编辑Card方法中,它将返回getCardValues()中的每个属性,而不仅仅是存在值实体的属性。

<强>更新

CardAttributeSet