从实体方法将选项加载到表单选择字段中


Load choices into form choice field from entity method

我有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:如果你真的想这样做,那么这里有一个方法:

  1. 修改你的静态属性$types,这样选择是一个数组中的值,例如,$types = array(1 => 'main', 2 => 'custom')
  2. 在你的控制器中,为Car实体添加一个use语句。
  3. 控制器动作:

    $car = new Car();

    $types = $car->getTypes;

  4. 使用答案传递数据到buildForm()在Symfony 2.8/3.0看看如何传递$types到您的表单。