symfony表单事件订阅者$ event-> getData()返回NULL

时间:2014-03-04 08:34:11

标签: php symfony symfony-forms

我创建了没有data_class的formType类:

$resolver->setDefaults(array(
        // 'data_class' => 'Mj\JobBundle\Entity\Ads', **i comment this**
 ));

首先是真的吗?

当我使用事件订阅者时:

$builder->addEventListener(
        FormEvents::PRE_SET_DATA,
        function(FormEvent $event) use ($formModifier) {
            $data = $event->getData();
            $f = $event->getForm();
            var_dump($data);
            echo 'hii';
        }
    );
  • $事件 - >的getData();总是返回NULL
  • 如果我取消注释'data_class'它的工作正常,但我不想这样做我该怎么办?

1 个答案:

答案 0 :(得分:1)

因为我没有注意到这个问题的日期,但我可能会对有类似问题的人稍微清楚一点。

假设您有一个包含某些字段的表单,并且您在没有data_class的情况下使用它。您始终可以使用Controller中createForm功能的第二个参数预设数据。例如:

class TestType extends AbstractType {

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

            // When passing a second argument to createForm you can get the data with $options['data']
            dump($options['data']);

            $builder
                ->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) {
                    // The $event will contain the preset data
                    dump($event->getData());
                })
                ->add('name', TextType::class)
                ->add('email', EmailType::class)
                ->add('message', TextareaType::class)
                ->add('send', SubmitType::class);
        }
    }

您将表单传递给预设的数据必须是一个数组,其中的键代表表单字段(例如nameemailmessagesend)和值显然是设置到表单字段的值。示例续:

public function formTestAction(Request $request) {

    // These values will be preset and are accessible with
    // $event->getData() (inside an EventListener) OR
    // through $options['data'] inside the buildForm function
    $myPreSetData = array(
        'name'      => 'Peter Griffin',
        'email'     => 'redFireTrucks@family-guy.com',
        'message'   => 'The fire truck can consume 8 times his body weight.'
    );

    $form = $this->createForm(TestType::class, $myPreSetData);

    $form->handleRequest($request);

    if($form->isSubmitted() && $form->isValid()) {
        dump('finished');
        dump($form->getData());
        die();
    }

    return $this->render('@TestPra/Test/test_form.html.twig', array(
        'form'  => $form->createView()
    ));


}

但您可能还希望在表单类中拥有与表单所代表的数据无关的数据,例如:设置ChoiceType字段的选项。在这种情况下,您通过createForm函数的第三个参数传递数据:

在控制器中:

$fireTruckColorChoices = array(
    'red'   => 0,
    'ultraRed'   => 1
);

$form = $this->createForm(TestType::class, $myPreSetData, array(
    'fireTruckColorChoices' => $fireTruckColorChoices
));

TestType类中,您必须根据需要设置传递选项的名称,在本例中为fireTruckColorChoices

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

        $builder
            ...
            ->add('fireTruckColor', ChoiceType::class, array(
                'choices'   => $options['fireTruckColorChoices'],
            ))
            ...;
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver) {
        // Must be set
        $resolver->setRequired(array(
            'fireTruckColorChoices'
        ));
    }
}

您可能还希望访问在EventListener闭包中作为选项传递的数据。在这种情况下,您只需要在表单中添加一个私有变量:

class TestType extends AbstractType {

    private $name;

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

        $this->name = $options['name'];

        $builder
            ->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) {
                dump($this->name);
            })
            ...;
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver) {
        $resolver->setRequired(array(
            'name'
        ));
    }
}