如何从 Symfony 实体中的数组制作 Select

How to make Select from array in Symfony Entity

我是 symfony 的新手并且还在学习,我的问题是如何在具有静态选项数组的表单中填充 select 下拉菜单。假设我有一个名为 Cake 的 class,我希望能够从创建的数组 statuses 中为 Cakestatus 填充下拉列表蛋糕实体:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\CakeRepository")
 */
class Cake
{
    /**
     * @ORM\Column(type="string", length=50)
     */

    private $status;

    private $statuses = array(
        'not_ready' => 'Not Ready',
        'almost_ready' => 'Almost Ready',
        'ready'=>'Ready',
        'too_late'=>'Too late'
    );
    public function getStatus(): ?string
    {
        return $this->status;
    }

    public function setStatus(string $status): self
    {
        $this->status = $status;
        return $this;
    }

    public function getStatuses()
    {
       return $this->statuses;
    }
}

我的控制器看起来像:

namespace App\Controller;

use App\Entity\Cake;
use App\Form\CakeType;
use App\Repository\CakeRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;


/**
 * @Route("/cake")
 */
class CakeController extends AbstractController
{
    /**
     * @Route("/new", name="cake_new", methods={"GET","POST"})
     */
    public function new(Request $request): Response
    {
        $cake = new Cake();
        $form = $this->createForm(CakeType::class, $cake);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

            $cake->setCreatedAt(\DateTime::createFromFormat('d-m-Y', date('d-m-Y')));
            $cake->setCreatedBy(1);
            $entityManager = $this->getDoctrine()->getManager();
            $entityManager->persist($cake);
            $entityManager->flush();

            return $this->redirectToRoute('cake_index');
        }

        return $this->render('cake/new.html.twig', [
            'cake' => $cake,
            'form' => $form->createView(),
        ]);
    }

我的 CakeEntity:

<?php

namespace App\Form;

use App\Entity\cake;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;

class CakeType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        ->add('status', ChoiceType::class,
            [
                'choices'=>function(?Cake $cake) {
                    return $cake->getStatuses();
                }
            ]);
    }
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Cake::class,
        ]);
    }
}

尝试浏览 /cake/new 时出现错误:

An error has occurred resolving the options of the form "Symfony\Component\Form\Extension\Core\Type\ChoiceType": The option "choices" with value Closure is expected to be of type "null" or "array" or "\Traversable", but is of type "Closure".

您可以将 Cake 上的 getStatuses 声明为 static,或使用 public 常量。例如:

class Cake
{
    // with static variables

    private static $statuses = [
        'not_ready'    => 'Not Ready',
        'almost_ready' => 'Almost Ready',
        'ready'        => 'Ready',
        'too_late'     => 'Too late',
    ];

    public static function getStatuses()
    {
        return self::$statuses;
    }

    // or with public const

    public const STATUSES = [
        'not_ready'    => 'Not Ready',
        'almost_ready' => 'Almost Ready',
        'ready'        => 'Ready',
        'too_late'     => 'Too late',
    ];
}

这似乎是合理的,因为 return 值不是实例而是 class 具体值。


然后您可以使用:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('status', ChoiceType::class, [
        'choices'=> Cake::getStatuses(),
    ]);

    // or

    $builder->add('status', ChoiceType::class, [
        'choices'=> Cake::STATUSES,
    ]);
}

如果选择实际上取决于给定的 Cake 实例,您可以通过选项数组传递它或使用 form events.