形式Symfony2中的依赖关系
我正在Symfony2中开发一个Web应用程序。 我来到了一个需要Symfony中更高级的建议/解释的地方。
我有一部分数据库设置如下:
我拥有属于卡片属性集并由卡片值组成的卡片。
我有卡属性集有很多属性,卡属性可以属于许多卡属性集(显然是多对多的关系)。
然后根据卡片属性,属性具有属性值,例如文本具有varchar类型的value_text和布尔类型为value_boolean的布尔值。
你可以想象当创建一张新的表单时,表单需要根据它所属的卡属性集来生成输入字段,并且取决于属性集属性的属性是否正确?
所以这是我的问题。 有没有一种方法可以根据用户选择的实体动态生成表单中的输入字段。 我已阅读过有关事件,但我不确定它们是否满足我的需求。
这是我实体的代码(为了更简单的视图,我将它移至Getters和Setters):
卡:
/**
* card
*
* @ORMTable()
* @ORMEntity(repositoryClass="clientsBundleEntitycardRepository")
* @UniqueEntity(
* fields={"cardLabel"},
* message="A card with this label already exists"
* )
*/
class card
{
/**
* @var integer
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORMColumn(name="card_label", type="string", length=999)
*/
private $cardLabel;
/**
* @ORMManyToOne(targetEntity="project", inversedBy="project_cards")
* @ORMJoinColumn(name="project_id", referencedColumnName="id", onDelete = "SET NULL")
*/
protected $card_project;
/**
* @ORMManyToOne(targetEntity="cardAttributeSet", inversedBy="cas_cards")
* @ORMJoinColumn(name="cas_id", referencedColumnName="id")
**/
protected $cardAttrSet;
/**
* @ORMOneToMany(targetEntity="cardAttrValue", mappedBy="card", cascade={"persist"}, orphanRemoval=true)
**/
protected $card_values;
/**
* @ORMManyToMany(targetEntity="user", mappedBy="cards")
*/
private $users;
public function __construct() {
$this->card_values = new ArrayCollection();
$this->users = new ArrayCollection();
}
}
卡属性:
/**
* cardAttribute
*
* @ORMTable()
* @ORMEntity(repositoryClass="clientsBundleEntitycardAttributeRepository")
* @UniqueEntity(
* fields={"name"},
* message="An attribute with this name already exists"
* )
*/
class cardAttribute
{
/**
* @var integer
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORMColumn(name="name", type="string", length=255)
*/
private $name;
/**
* @var string
*
* @ORMColumn(name="type", type="string", length=255)
*/
private $type;
}
卡属性集
/**
* cardAttributeSet
*
* @ORMTable()
* @ORMEntity(repositoryClass="clientsBundleEntitycardAttributeSetRepository")
* @UniqueEntity(
* fields={"casLabel"},
* message="An attribute set with this label already exists"
* )
*/
class cardAttributeSet
{
/**
* @var integer
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
public $id;
/**
* @var string
*
* @ORMColumn(name="cas_label", type="string", length=255)
*/
private $casLabel;
/**
* @ORMOneToMany(targetEntity="card", mappedBy="cardAttrSet")
*/
private $cas_cards;
/**
* @ORMManyToMany(targetEntity="cardAttribute")
* @ORMJoinTable(name="cas_attribute",
* joinColumns={@ORMJoinColumn(name="cas_id", referencedColumnName="id")},
* inverseJoinColumns={@ORMJoinColumn(name="attribute_id", referencedColumnName="id")}
* )
*/
private $attributes;
public function __construct()
{
$this->cas_cards = new ArrayCollection();
$this->attributes = new ArrayCollection();
}
}
卡属性值
/**
* cardAttrValue
*
* @ORMTable()
* @ORMEntity(repositoryClass="clientsBundleEntitycardAttrValueRepository")
* @UniqueEntity(
* fields={"valueText"}
* )
*/
class cardAttrValue
{
/**
* @var integer
*
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORMColumn(name="value_text", type="string", length=255, nullable=true)
*/
private $valueText;
/**
* @var string
*
* @ORMColumn(name="value_varchar", type="string", length=255, nullable=true)
*/
private $valueVarchar;
/**
* @var integer
*
* @ORMColumn(name="value_int", type="integer", nullable=true, nullable=true)
*/
private $valueInt;
/**
* @var boolean
*
* @ORMColumn(name="value_boolean", type="boolean", nullable=true, nullable=true)
*/
private $valueBoolean;
/**
* @ORMManyToOne(targetEntity="card", inversedBy="card_values")
* @ORMJoinColumn(name="card_id", referencedColumnName="id")
**/
private $card;
/**
* @ORMManyToOne(targetEntity="cardAttribute")
* @ORMJoinColumn(name="cardAttributes_id", referencedColumnName="id")
**/
private $cardAttribute;
}
为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
}
}
}
然后,在CardType
表单类型内添加card_values
collection
字段类型,并将CardAttributeValueType
作为集合项目类型传递。
在Card
实体中编辑getCardValues()
方法,以便它将返回CardAttributeSet
每个属性,而不仅仅是存在其值实体的属性。
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;
}
链接地址: http://www.djcxy.com/p/27107.html