【问题标题】:symfony2 - adding choices from databasesymfony2 - 从数据库中添加选择
【发布时间】:2021-11-03 22:00:34
【问题描述】:

我希望使用自定义查询中的值填充 symfony2 中的选择框。我已经尽量简化了。

控制器

class PageController extends Controller
{

    public function indexAction()
    {
      $fields = $this->get('fields');
      $countries =  $fields->getCountries(); // returns a array of countries e.g. array('UK', 'France', 'etc')
      $routeSetup = new RouteSetup(); // this is the entity
      $routeSetup->setCountries($countries); // sets the array of countries

      $chooseRouteForm = $this->createForm(new ChooseRouteForm(), $routeSetup);


      return $this->render('ExampleBundle:Page:index.html.twig', array(
        'form' => $chooseRouteForm->createView()
      ));

    }
}

选择路由表单

class ChooseRouteForm extends AbstractType
{

  public function buildForm(FormBuilderInterface $builder, array $options)
  {

    // errors... ideally I want this to fetch the items from the $routeSetup object 
    $builder->add('countries', 'choice', array(
      'choices' => $this->routeSetup->getCountries()
    ));

  }

  public function getName()
  {
    return 'choose_route';
  }
}

【问题讨论】:

    标签: php forms symfony drop-down-menu populate


    【解决方案1】:

    您可以使用...将选项传递给您的表单。

    $chooseRouteForm = $this->createForm(new ChooseRouteForm($routeSetup), $routeSetup);
    

    然后以你的形式..

    private $countries;
    
    public function __construct(RouteSetup $routeSetup)
    {
        $this->countries = $routeSetup->getCountries();
    }
    
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('countries', 'choice', array(
            'choices' => $this->countries,
        ));
    }
    

    针对 2.8+ 进行了更新(和改进)

    首先,您实际上不需要将国家/地区作为路线对象的一部分传递,除非它们将存储在数据库中。

    如果将可用国家/地区存储在数据库中,则可以使用事件侦听器。如果没有(或者如果您不想使用监听器),您可以在选项区域中添加国家/地区。

    使用选项

    在控制器中..

    $chooseRouteForm = $this->createForm(
        ChooseRouteForm::class,
        // Or the full class name if using < php 5.5
        $routeSetup,
        array('countries' => $fields->getCountries())
    );
    

    在你的表单中..

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('countries', 'choice', array(
            'choices' => $options['countries'],
        ));
    }
    
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver
            ->setDefault('countries', null)
            ->setRequired('countries')
            ->setAllowedTypes('countries', array('array'))
        ;
    }
    

    使用监听器(如果国家/地区数组在模型中可用)

    在控制器中..

    $chooseRouteForm = $this->createForm(
        ChooseRouteForm::class,
        // Or the full class name if using < php 5.5
        $routeSetup
    );
    

    在你的表单中..

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) {
                $form = $event->getForm();
                /** @var RouteSetup $routeSetup */
                $routeSetup = $event->getData();
    
                if (null === $routeSetup) {
                    throw new \Exception('RouteSetup must be injected into form');
                }
    
                $form
                    ->add('countries', 'choice', array(
                        'choices' => $routeSetup->getCountries(),
                    ))
                ;
            })
        ;
    }
    

    【讨论】:

    • 因此,从 Symfony 2.8 开始,不推荐传入实例化的表单类。现在您需要传递完全限定的类名。这使我们无法使用构造函数......这很糟糕,因为我不想像我的情况那样从控制器加载选项,这个选择字段是从许多控制器中使用的,并且构造起来很有意义表单类中的选项,但是,如何在不使用选项或服务的情况下让学说管理器进入表单类......? hack hack hack,除非我错过了什么,请说出来
    • 老实说,即使在那时这也不是最好的方法。我会更新的。
    • 不用担心,您的帖子是 2013 年的,而 2.8 就像几个月前一样。感谢您的更新...我现在就开始玩它
    • 如果您确实需要帮助,那么我会提出一个问题,我可以在其中给出答案,而不是在 cmets 或给定答案中添加令人困惑的答案。
    • 不,谢谢,我现在好像到了。不过欣赏它,很抱歉挖掘了旧帖子:)
    【解决方案2】:

    我还不能评论或投反对票,所以我将在这里回复 Qoop 的回答: 除非您开始将表单类型类用作服务,否则您提出的建议将起作用。 您通常应该避免通过构造函数向表单类型对象添加数据。

    form type 类想象成 Class - 它是对表单的一种描述。当您创建一个表单实例(通过构建它)时,您将获得由表单类型中的描述构建然后填充数据的表单的对象

    看看这个:http://www.youtube.com/watch?v=JAX13g5orwo - 在演示文稿的 31 分钟左右描述了这种情况。

    您应该使用表单事件 FormEvents::PRE_SET_DATA 并在表单被注入数据时操作字段。 见:http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#customizing-your-form-based-on-the-underlying-data

    【讨论】:

    • 这样做有什么好处?为什么不检查是否设置了表单数据$routesetup?如果没有,不要添加字段/抛出一个不错的错误?
    • 这是最佳实践方法,我只是更正了问题中的代码以使其正常工作,而不是“改进”它。我现在用提到的`PRE_SET_DATA 方法和另一个方法更新了我的答案(由于新评论,而不是我疯了,重新阅读了我两年前的答案)。
    【解决方案3】:

    我通过在构建器上调用 getData 使其工作

    FormBuilderInterface $builder
    

    // 控制器

    $myCountries = $this->myRepository->all(['continent' => 'Africa']);
    $form = $this->createForm(CountriesType::class, $myCountries);
    

    //表单类型

    use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
    
    public function buildForm(FormBuilderInterface $builder, array $options): void
        {
            $builder
                ->add('pages', ChoiceType::class, [
                    'choices' => $builder->getData()
                ])
            ;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-22
      • 2013-03-02
      • 2012-01-01
      相关资源
      最近更新 更多