我有symfony表单与选择字段。我想从实体类静态方法中加载选择。我可以使用data或CallbackChoiceLoader吗?什么是最佳实践?
this is my field:
class CarType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('type', ChoiceType::class, [
// This choices I would like to load from:
// 'choices' => $car::getTypes(),
'choices' => [
'Critical' => 'critical',
'Medium' => 'medium',
'Info' => 'info',
],
'label' => 'Type'
])
->add('name', TextType::class, [
'label' => 'Name'
])
->add('save', SubmitType::class, [
'label' => 'Save'
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'AppBundle'Entity'Car'
]);
}
public function getName()
{
return 'car';
}
}
这是我的实体:
/**
* @ORM'Entity
* @ORM'Table(name="car")
*/
class Car
{
/**
* @var integer
*
* @ORM'Column(name="id", type="integer", nullable=false)
* @ORM'Id
* @ORM'GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string $type
*
* @Assert'NotBlank()
* @ORM'Column(name="type")
*/
private $type;
/**
* @var string $name
*
* @Assert'NotBlank()
* @ORM'Column(name="name")
*/
private $name;
/**
* @var 'DateTime $created
*
* @ORM'Column(name="created", type="datetime")
*/
private $created;
private static $types = ['main', 'custom'];
public function __construct()
{
$this->created = new 'DateTime('now', new 'DateTimeZone('Europe/Ljubljana'));
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Get types
*
* @return array
*/
public function getTypes()
{
return self::$types;
}
/**
* Set type
*
* @param string $type
*
* @return Car
*/
public function setType($type)
{
if (in_array($type, $this->getTypes())) {
$this->type = $type;
}
return $this;
}
/**
* Get type
*
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* Set name
*
* @param string $name
*
* @return Car
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set created
*
* @param 'DateTime $created
*
* @return Car
*/
public function setCreated($created)
{
$this->created = $created;
return $this;
}
/**
* Get created
*
* @return 'DateTime
*/
public function getCreated()
{
return $this->created;
}
如何和我可以用什么来加载$car::getTypes()方法的选择,就像我在表单中评论的那样,以便根据getTypes实体方法中的值动态加载选择?
编辑:这是选项1。选项2更直接地回答了这个问题。
从实体创建选择表单字段的首选方法是使用EntityType字段。下面是一个需要种族字段的应用程序示例。下面是Ethnicity实体。
表单字段:
->add('ethnicity', EntityType::class, array(
'label' => 'Ethnicity:',
'class' => 'AppBundle:Ethnicity',
'choice_label' => 'abbreviation',
'expanded' => false,
'placeholder' => 'Select ethnicity',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('e')
->orderBy('e.abbreviation', 'ASC')
;
},
))
民族实体:
/**
* Ethnicity.
*
* @ORM'Table(name="ethnicity")
* @ORM'Entity
*/
class Ethnicity
{
/**
* @var int
*
* @ORM'Column(name="id", type="integer")
* @ORM'Id
* @ORM'GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* @var string
*
* @ORM'Column(name="ethnicity", type="string", length=45, nullable=true)
*/
protected $ethnicity;
/**
* @var string
*
* @ORM'Column(name="abbr", type="string", length=45, nullable=true)
*/
protected $abbreviation;
/**
* @var 'Doctrine'Common'Collections'Collection
*
* @ORM'OneToMany(targetEntity="AppBundle'Entity'Member", mappedBy="ethnicity", cascade={"persist"})
*/
protected $members;
/**
* Constructor.
*/
public function __construct()
{
$this->members = new 'Doctrine'Common'Collections'ArrayCollection();
}
/**
* Get id.
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set ethnicity.
*
* @param string $ethnicity
*
* @return Ethnicity
*/
public function setEthnicity($ethnicity)
{
$this->ethnicity = $ethnicity;
return $this;
}
/**
* Get ethnicity.
*
* @return string
*/
public function getEthnicity()
{
return $this->ethnicity;
}
/**
* Set abbreviation.
*
* @param string $abbreviation
*
* @return Ethnicity
*/
public function setAbbreviation($abbreviation)
{
$this->abbreviation = $abbreviation;
return $this;
}
/**
* Get abbreviation.
*
* @return string
*/
public function getAbbreviation()
{
return $this->abbreviation;
}
/**
* Add members.
*
* @param 'AppBundle'Entity'Member $members
*
* @return Ethnicity
*/
public function addMember('AppBundle'Entity'Member $members)
{
$this->members[] = $members;
return $this;
}
/**
* Remove members.
*
* @param 'AppBundle'Entity'Member $members
*/
public function removeMember('Truckee'ProjectmanaBundle'Entity'Member $members)
{
$this->members->removeElement($members);
}
/**
* Get members.
*
* @return 'Doctrine'Common'Collections'Collection
*/
public function getMembers()
{
return $this->members;
}
/**
* @var bool
*
* @ORM'Column(name="enabled", type="boolean", nullable=true)
*/
protected $enabled;
/**
* Set enabled.
*
* @param bool $enabled
*
* @return enabled
*/
public function setEnabled($enabled)
{
$this->enabled = $enabled;
return $this;
}
/**
* Get enabled.
*
* @return bool
*/
public function getEnabled()
{
return $this->enabled;
}
}
选项2:如果你真的想这样做,那么这里有一个方法:
- 修改你的静态属性
$types
,这样选择是一个数组中的值,例如,$types = array(1 => 'main', 2 => 'custom')
- 在你的控制器中,为Car实体添加一个use语句。
控制器动作:
$car = new Car();
$types = $car->getTypes;
使用答案传递数据到buildForm()在Symfony 2.8/3.0看看如何传递
$types
到您的表单。