【问题标题】:inject entitymanager in form type using service使用服务以表单类型注入 entitymanager
【发布时间】:2016-03-21 11:44:57
【问题描述】:

我使用 symfony2.7,当我想将 entitymanager 注入表单类型时遇到问题,但我没有看到在我的服务上调用了 __construct(),并且注入不起作用。 我使用服务将实体管理器注入到我的表单类型中。

public function createValeurChampNomenclatureAction(Request $request) {
        $em = $this->getDoctrine()->getManager();        
        $cgaValeurChampNomenclature = new CGAValeurchampnomenclature();
        $form = $this->createForm('espritApp_nomenclaturebundle_cgavaleurchampnomenclature', $CGAValeurChampNomenclature);
....

在我的表单类型中我创建了我的构造

     class CGAValeurChampNomenclatureType extends AbstractType
{

  /**
 * @var EntityManager $entityManager Entity manager
 */
    private $em;

    /**
 * Constructor
 *
 * @param EntityManager $entityManager Entity manager
 */
    public function _construct(EntityManager $entityManager)
    {
        $this->em=$entityManager;


    }

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder
            ->add('cgatypenome','entity', array(
                    'class' => 'EspritAppNomenclatureBundle:CGATypenomenclature',
                    'property' => 'codeStr',
                    'multiple'  => false,
                    'required'    => true,
                    'attr'=> array('class'=>'form-control select2 codeStr'))
                    )
            ->add('cgacodenomenclature','choice', array('required' => TRUE,
             'attr' => array('placeholder' => 'Code nomenclature','class'=>'form-control select2 codeNomenclature')
                ))
          ->add('cgachamptypenome','choice', array('required' => TRUE,
             'attr' => array('placeholder' => 'Code Champ','class'=>'form-control select2 codeChampNomenclature')
                ))
         ->add('chaCodeStr','text', array('required' => TRUE,
             'attr' => array('placeholder' => 'Champ code Str','class'=>'form-control')
                ))
                ->add('valeur','text', array('required' => TRUE,
             'attr' => array('placeholder' => 'valeur','class'=>'form-control')
                ));


        $formModif = function (FormInterface $form, $codeStr) 
        {             
            $listChampTypeNome = $this->em->getRepository('EspritAppNomenclatureBundle:CGAChamptypenomenclature')->getListChampTypeNomenclatureByCodeStr($codeStr);                       
            $listCodeNome = $this->em->getRepository('EspritAppNomenclatureBundle:CGACodenomenclature')->getListCodeNomenclatureByCodeStr($codeStr);

             if ($listChampTypeNome) {
                $ChampsTypeNome = array();
                foreach($listChampTypeNome as $ChampTypeNome) {
                    $ChampsTypeNome[] = $ChampTypeNome->getCodeChamp();                   
                }
            } else {
                $ChampsTypeNome = null;
            }


             if ($listCodeNome) {
                $CodesNome = array();
                foreach($listCodeNome as $CodeNome) {
                    $CodesNome[] = $CodeNome->getCodeNome();                   
                }
            } else {
                $CodesNome = null;
            }


            $form->add('cgacodenomenclature','choice', array('required' => TRUE,
             'attr' => array('placeholder' => 'Code nomenclature','class'=>'form-control select2 codeNomenclature'),'choices' =>$ChampsTypeNome)
                )
                ->add('cgachamptypenome','choice', array('required' => TRUE,
             'attr' => array('placeholder' => 'Code Champ','class'=>'form-control select2 codeChampNomenclature'),'choices'=>$CodesNome)
                );
        };

        $builder->get('cgacodenomenclature')->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use ($formModif){
            $formModif($event->getForm()->getParent(),$event->getForm()->getData());
        });




    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'EspritApp\NomenclatureBundle\Entity\CGAValeurchampnomenclature'
        ));
    }

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

这是我在 services.yml 中的服务

 app.form.type.cgavaleurchampnome:
        class:  EspritApp\NomenclatureBundle\Form\CGAValeurChampNomenclatureType
        tags:
            - { name: form.type, alias: espritApp_nomenclaturebundle_cgavaleurchampnomenclature }
        arguments: [@doctrine.orm.entity_manager]

我得到这个错误的问题:

在非对象上调用成员函数 getRepository()

【问题讨论】:

  • 您使用的是哪个版本的 Symfony。 2.8/3.0 有重大的形式变化。
  • 在 symofny2 中通过构造函数将某些东西传递给 formType 不是一个好习惯,请使用第三个参数(选项),其次,为什么要在表单类型中使用实体管理器?也许我们可以找到更好的方法来解决您的问题
  • 请尝试添加一些关于该问题的附加信息。此外,在var_dump($this->em); 之后添加代码可能有助于解决问题。
  • 我如何使用第三个参数选项? @Kamil_oos
  • 查看此页面:symfony.com/doc/current/book/forms.html#creating-form-classes 选项在 $options 中可用。将选项传递给这个变量: $form = $this->createForm(TaskType::class, $task, ['option' => 'option']);

标签: php forms symfony dependency-injection dependencies


【解决方案1】:

我怀疑您需要一个 use 语句才能在此处访问 $em:

$em = $this->em;
$formModif = function (FormInterface $form, $codeStr ) use $em
{
  die(get_class($em));

虽然你为什么要这样做很令人费解。 http://php.net/manual/en/functions.anonymous.php

【讨论】:

  • 我想从另一个列表中填充两个列表框
  • 我没有看到在我的服务上调用了 __construct(),并且注入不起作用。
【解决方案2】:

您可以轻松地将表单定义为服务并将 EntityManager 传递给那里。为此,您应该以如下形式定义 getName 函数:

/**
 * {@inheritdoc}
 */
public function getName()
{
    return 'my_form';
} 

并将这种表单类型定义为服务:

app.form.task:
    class: AppBundle\Form\Type\MyFormType
    tags:
        - { name: form.type, alias: my_form }
    arguments:
        - "@doctrine.orm.entity_manager"

之后,你可以在构造函数中获取 EntityManager 对象并以整个形式使用它。

/**
 * @var EntityManager $entityManager Entity manager
 */
private $em;

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

使用示例:

/**
 * {@inheritdoc}
 */
public function finishView(FormView $view, FormInterface $form, array $options)
{
    $users = $this->em->getRepository('AppBundle:User')->findAll();

    $view->vars['users'] = $users;
}

现在您还可以像这样在控制器中使用表单类型:

$form = $this->createForm('my_form');

这就是你要找的吗?

【讨论】:

  • 是的,这正是我所需要的@Logans,但是当我调用 $this->em->getRepository 时出现此错误“调用非对象上的成员函数 getRepository()”
  • 尝试像@Cerad 所说的那样$em = $this->em; function (FormInterface $form, $codeStr) use $em { // Other stuff }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-15
  • 2017-10-23
  • 2023-03-11
  • 1970-01-01
  • 2021-10-29
相关资源
最近更新 更多