【问题标题】:How to pass option when creating form创建表单时如何传递选项
【发布时间】:2015-06-20 13:23:03
【问题描述】:

我正在处理一个表单,并希望将一个数组传递给我的表单,该数组将包含我的所有项目,以便我的表单可以选择包含所有这些项目的选项。

我已经回答了很多,但我就是想不通这件事。我知道我应该做类似的事情:

$formulaire=$this->createForm(new ModifierSupprimerProjet(), null, $myArray);

但是,我想将我的数组的所有内容添加到 getDefaultOptions()... 我这样做吗?另一件事,createForm 方法的第二个参数应该是什么?

这是最接近解决我的问题的帖子:

Accessing a variable through $options in the buildForm()

【问题讨论】:

标签: php forms symfony


【解决方案1】:

使用项目实体填充选择表单元素的最佳方法是使用entity form field。所以你不必传递任何选项来形成类型类。

$builder
    ->add('project', 'entity', [
        'label'         => 'form.project',
        'class'         => 'AppBundle\Entity\Project',
        'property'      => 'name',
        'required'      => true,
        'empty_value'   => 'form.select_empty_value',
        'query_builder' => function($repository) {
            return $repository->createQueryBuilder('p')->add('orderBy', 'p.name ASC');
        },
    ])
;

如果您需要填充 choice field,还有另一个最佳实践。您应该将表单类型类定义为服务并将 Entity Manager 注入其中。因此,您可以从数据库中获取任何数据并填充任何选择字段。

services.xml

<service id="app.form.modifier_supprimer_projet" class="AdminBundle\Form\ModifierSupprimerProjet">
    <tag name="form.type" alias="app_modifier_supprimer_projet" />
    <argument type="service" id="doctrine.orm.entity_manager"/>
</service>

修饰符SupprimerProjet.php

<?php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Doctrine\ORM\EntityManager;

class ModifierSupprimerProjet extends AbstractType
{
    /**
     * @var EntityManager
     */
    protected $em;

    /**
     * @param EntityManager $em
     */
    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('project', 'choice', [
                'label'   => 'form.project',
                'choices' => $this->em->getRepository('AppBundle:Project')->getProjectsList(),
            ])
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults([    
            'data_class' => 'AppBundle\Entity\ModifierSupprimerProjet',
        ]);     
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'app_modifier_supprimer_projet';
    }
}

控制器

$modifierSupprimerProjet = new ModifierSupprimerProjet();

$form = $this->createForm('app_modifier_supprimer_projet', $modifierSupprimerProjet);

createForm 方法的第二个参数是实体,如果您的表单映射到任何实体。

【讨论】:

    【解决方案2】:

    前段时间我不得不做类似的事情,我必须获取图标列表并将其传递给表单,这就是我实现它的方法。

    在我的行动中

    // my entity
    $services = new Services();
    
    $icons = the query for icons, in your case the projects
    
    // creating form view, notice 'icons' being passed to the form
    $form = $this->createForm(new AddServices(), $services, array('icons' => $icons));
    

    在你的表单类中

    namespace Acme\YourBundle\Form;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    
    class AddServices extends AbstractType
    {
    
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
    
    //build your form here
            $builder->add('....');
            //form field linked with your dropdown options, in your case the projects
            $builder->add('icon', 'choice', array(
                'choices'   => $options['icons'],
                'required'  => false,
            ));
    
        }
    
        public function getName()
        {
            return 'addServices';
        }
    
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            //notice icons being set here as default options
            $resolver->setDefaults(array(
                'icons' => null,
            ));
        }
    }
    

    然后在你的树枝里面 {{ form_widget(form.icon, { 'attr': {'class': ''} }) }}

    我确信可能还有其他方法可以实现这一点,但这就是我的做法,而且似乎工作得很好

    【讨论】:

    • 谢谢,它工作得很好,但我想知道为什么你需要设置默认选项?我的意思是,例如,在一个函数中,你可以传递你想要的任何东西,它就会接受它。在这里,已经有一个参数选项是一个数组,那么为什么我们不能直接过去任何数组呢?为什么我们需要明确说明我们将在这个数组中拥有什么?
    【解决方案3】:

    我们假设您已经阅读了documentation,但不明白如何使用它。非常简单,表单类型中有3个重要方法,buildForm 用于构建表单的字段, setDefaultOptions 用于版本 configureOptions 用于版本 >2.6,您可以指定 buildForm 方法(内部由表单组件)使用的选项,getName - 表单的唯一名称(here is a对此方法的简单说明)。

    如果我们回到您的问题,您可以像这样解决您的任务:

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver
            ->setDefaults([
                'data_class' => 'YOUR_ENTITY' /* FormComponent autmatically maps the form fields with your entity if you set this option and pass an object as an 2-arguement to `createForm` method in your controller */
                'my_custom_option' => null /* here we specify our custom option and set its initial value as null */
            ])
            ->setRequired([ /* this is optional, which tells the 'my_custom_option' option is required */
                'my_custom_option'
            ])
            ->setAllowedTypes([ /* this one is also optional, which specify the type your 'my_custom_option' option */
                'my_custom_option' => 'Symfony\Component\HttpFoundation\Request' // this is an example, which allows only `request` object
            ])
         ;
    }
    
    public function buildForm(...)
    {
        $myCustomOption = $options['my_custom_option']; // here we get our 'my_custom_option'
    
        ....
    }
    

    在您的控制器中:

    $formulaire=$this->createForm(new ModifierSupprimerProjet(), OBJECT_OR_NULL /* here we set our object which we've already assigned to `data_class` or we set to NULL */, [
         'my_custom_option' => $request
    ]);
    

    【讨论】:

      猜你喜欢
      • 2018-09-07
      • 2020-03-29
      • 2018-05-09
      • 1970-01-01
      • 2016-09-13
      • 1970-01-01
      • 1970-01-01
      • 2016-10-02
      • 1970-01-01
      相关资源
      最近更新 更多