1

从 2.1 更新到 Symfony 2.3 后,当我尝试创建表单时出现一条奇怪的消息:

可捕获的致命错误:传递给 msgr\ProfileBundle\Form\EventListener\AddNameFieldSubscriber::preSetData() 的参数 1 必须是 Symfony\Component\Form\Event\DataEvent 的实例,/xxxxxx 中给出的 Symfony\Component\Form\FormEvent 的实例/aaas/src/msgr/ProfileBundle/Form/EventListener/AddNameFieldSubscriber.php 第 29 行

这些是通常的嫌疑人:

配置文件类型.php

    <?php

namespace aaas\ProfileBundle\Form;

use Doctrine\ORM\EntityRepository;

use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use aaas\ProfileBundle\Form\EventListener\AddNameFieldSubscriber;


class ProfileType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $subscriber = new AddNameFieldSubscriber($builder->getFormFactory());
        $builder->addEventSubscriber($subscriber);
        $builder
            ->add('firstname')
            ->add('lastname')
            ->add('city')
            ->add('country')
            ->add('mobile')
            ->add('description')
            ->add('avatarFile')
            ->add('website')
            ->add('facebook')
            ->add('twitter')
            ->add('googlePlus')
            ->add('gender', 'choice', array(
                'choices'   => array('M' => 'man', 'F' => 'female'),
                'required'  => true,
                'empty_value' => 'choose your gender',
            ))
            ;        
    }

    //public function getParent()
    //{
    //    return 'form';
    //}

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'aaas\ProfileBundle\Entity\Profile'
        ));
    }

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

AddNameFieldSubscriber.php

<?php
// src/Acme/DemoBundle/Form/EventListener/AddNameFieldSubscriber.php
namespace aaas\ProfileBundle\Form\EventListener;


use Symfony\Component\Form\FormFactoryInterface;
use Doctrine\ORM\EntityManager;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\Event\DataEvent;


class AddNameFieldSubscriber implements EventSubscriberInterface
{
    private $factory;

    public function __construct(FormFactoryInterface $factory)
    {
        $this->factory = $factory;
    }

    public static function getSubscribedEvents()
    {
        // Tells the dispatcher that we want to listen on the form.pre_set_data
        // event and that the preSetData method should be called.
        return array(FormEvents::PRE_SET_DATA => 'preSetData');
    }

    public function preSetData(DataEvent $event)
    {
        //$data = $event->getData();
        $form = $event->getForm();

        // During form creation setData() is called with null as an argument
        // by the FormBuilder constructor. We're only concerned with when
        // setData is called with an actual Entity object in it (whether new,
        // or fetched with Doctrine). This if statement let's us skip right
        // over the null condition.
        if (null === $data) {
            return;
        }

        // check if the product object is "new"

        if (!$data->getId()) {
            $form->add($this->factory->createNamed('username','text', array(
                                                   'auto_initialize' => false
                                                    )));
            $form->add($this->factory->createNamed('password','password'));
            $form->add($this->factory->createNamed('email','email'));
            $form->add($this->factory->createNamed('groups', 'entity',null, array(
                                                   'multiple' => false,
                                                   'class' => 'aaasProfileBundle:Group',
                                                   'query_builder' => function(EntityRepository $er) {
                                                                         return $er->createQueryBuilder('g')
                                                                                     ->where('g.id != 1')
                                                                                     ->andwhere('g.id != 2')
                                                                                     ->andwhere('g.id != 3');
                                                      }
                                                  )));
        }

    }
}

不幸的是,我找不到问题的根本原因!

4

2 回答 2

3

您的类AddNameFieldSubscriber有一个方法public function preSetData(DataEvent $event),应该改为为FormEvent. Form 组件更改了在 2.1 和 2.3 之间分派的 Event 对象:

<?php
// src/Acme/DemoBundle/Form/EventListener/AddNameFieldSubscriber.php
namespace aaas\ProfileBundle\Form\EventListener;


use Symfony\Component\Form\FormFactoryInterface;
use Doctrine\ORM\EntityManager;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;


class AddNameFieldSubscriber implements EventSubscriberInterface
{
    private $factory;

    public function __construct(FormFactoryInterface $factory)
    {
        $this->factory = $factory;
    }

    public static function getSubscribedEvents()
    {
        // Tells the dispatcher that we want to listen on the form.pre_set_data
        // event and that the preSetData method should be called.
        return array(FormEvents::PRE_SET_DATA => 'preSetData');
    }

    public function preSetData(FormEvent $event)
    {
        //$data = $event->getData();
        $form = $event->getForm();

        // During form creation setData() is called with null as an argument
        // by the FormBuilder constructor. We're only concerned with when
        // setData is called with an actual Entity object in it (whether new,
        // or fetched with Doctrine). This if statement let's us skip right
        // over the null condition.
        if (null === $data) {
            return;
        }

        // check if the product object is "new"

        if (!$data->getId()) {
            $form->add($this->factory->createNamed('username','text'));
            $form->add($this->factory->createNamed('password','password'));
            $form->add($this->factory->createNamed('email','email'));
            $form->add($this->factory->createNamed('groups', 'entity',null, array(
                                                   'multiple' => false,
                                                   'class' => 'aaasProfileBundle:Group',
                                                   'query_builder' => function(EntityRepository $er) {
                                                                         return $er->createQueryBuilder('g')
                                                                                     ->where('g.id != 1')
                                                                                     ->andwhere('g.id != 2')
                                                                                     ->andwhere('g.id != 3');
                                                      }
                                                  )));
        }

    }
}
于 2013-07-10T21:39:13.147 回答
2

错误消息几乎可以告诉您。

改变:

use Symfony\Component\Form\Event\DataEvent;
...
public function preSetData(DataEvent $event)

至:

use Symfony\Component\Form\Event\FormEvent;
...
public function preSetData(FormEvent $event)

德拉斯!@John Kary 打败了我。

于 2013-07-10T21:40:15.430 回答