symfony 3:如何在表单类型的addEventSubscriber中获取更新的数据?

时间:2018-07-16 08:47:09

标签: symfony symfony-forms symfony-3.4 symfony-eventdispatcher

Symfony版本:3.4

我有一个根形式是布局形式,其中包括一个被称为块的集合类型。内容形式属于块形式。我想使用ajax来使用户更改选择器1的值,然后将窗体类型2更改为其他窗体类型。

可以在$ request->控制器中的请求中选择更新后的选定值。

但是我无法获得选择器1的新数据,它始终是旧数据。

LayoutType.php

class LayoutType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name', TextType::class, array(
            'attr' => array(
                'class' => 'form-control'
            ),
            'label' => 'name'
        ));

        $builder->add('blocks', CollectionType::class, array(
            'entry_type' => BlockType::class,
            'entry_options' => array('label' => false),
            'allow_add' => true,
            'allow_delete' => true,
            'required' => false,
            'label' => false
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => '****\Bundle\****Bundle\Entity\Layout'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'layout_form';
    }
}

BlockType.php

class BlockType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name', TextType::class, array(
            'attr' => array(
                'class' => 'form-control layout-block-name'
            ),
            'label' => '名称'
        ));
        $builder->add('contents', CollectionType::class, array(
            'entry_type' => BlockContentType::class,
            'entry_options' => array('label' => false),
            'allow_add' => true,
            'allow_delete' => true,
            'required' => false,
            'label' => false
        ));
    }/**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => '****\Bundle\****Bundle\Entity\LayoutBlock'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'layout_block_form';
    }
}

BlockContentType.php

class BlockContentType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $factory = $builder->getFormFactory();
        $builder->addEventSubscriber(new BlockContentValueFieldSubscriber($factory));
        $builder->add('unit', TextType::class, array(
            'attr' => array(
                'class' => 'form-control block-content-unit',
                'placeholder' => '默认单位'
            ),
            'required' => false,
            'label' => '默认单位'
        ));
        $builder->add('option', EntityType::class, array(
            'class' => '*******Bundle:FormFieldOption',
            'choice_label' => 'name',
            'attr' => array(
                'class' => 'form-control'
            ),
            'label' => '表单选项'
        ));
        $builder->add('type', ChoiceType::class, array(
            'attr' => array(
                'class' => 'form-control select-block-content-form-type'
            ),
            'choices' => array(
                '文本'   => 'textarea',
                '下拉菜单'   => 'select',
                '图片'      => 'image'
            ),
            'preferred_choices' => array('textarea'),
            'label' => 'Form TYpe'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => '****\Bundle\****Bundle\Entity\LayoutBlockContent'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'block_content_form';
    }
}

BlockContentValueFieldSubscriber.php

class BlockContentValueFieldSubscriber implements EventSubscriberInterface
{
    protected $factory;
    public function __construct(FormFactoryInterface $factory)
    {
        $this->factory = $factory;
    }

    public static function getSubscribedEvents()
    {
        return array(
            FormEvents::PRE_SET_DATA => 'preSetData',
        );
    }

    public function preSetData(FormEvent $event)
    {
        $data = $event->getData();
        $form = $event->getForm();
        if (!($data instanceof LayoutBlockContent) || !$data->getBlock()) {
            $form->add('value', TextareaType::class, array(
                'attr' => array(
                    'class' => 'form-control block-content-input-value form-textarea-type'
                )
            ));
        } else {
            $type = $data->getType();
            // $type always is old data not the ajax data
            switch ($type)
            {
                case 'image':
                    $form->add('value', FileType::class, array(
                        'data_class' => null,
                        'attr' => array(
                            'class' => 'form-control block-content-input-value form-image-type'
                        )
                    ));
                    break;
                default:
                    $form->add('value', TextareaType::class, array(
                        'attr' => array(
                            'class' => 'form-control block-content-input-value form-textarea-type'
                        )
                    ));
                    break;
            }
        }
    }
}

enter image description here

enter image description here

0 个答案:

没有答案