[英]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.