Symfony 3-表单模型数据丢失了属性值,这些属性值未由字段表示 [英] Symfony 3 - Form model data loses property values which are not represented by fields

查看:59
本文介绍了Symfony 3-表单模型数据丢失了属性值,这些属性值未由字段表示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个控制器操作方法,该方法应该处理两个分割的表格.每个表单仅处理我的实体 Workflow 的一些属性.提交第一个表单后,我可以毫无问题地创建和呈现第二个表单.现在的问题:

I have a controller action method which should handle a two-splitted form. Each form handles just a few properties of my Entity Workflow. After submitting the first form I can create and render the second form without problems. Now the problem:

提交第二种形式后,在第一种形式中设置的所有值的信息都消失了,这意味着在调用 submit (或 handleRequest )时,此处没有任何区别)实体对象仅保存以第一种形式设置的属性的数据,甚至无法正确解析某些值.

After submitting the second form, the information of all values set in the first form are gone which means that when calling submit (or handleRequest does not make any difference here) the entity object only holds data of the properties set in the first form and it even can´t resolve some values properly.

以下是控制器(带有一些注释):

Here is the Controller (with some comments):

public function createWorkflowAction(Request $request, Project $project, Workflow $workflow = null) {   

    if(!$workflow) {
        $workflow = new Workflow($project);
    }

    $firstFormPart = $this->createForm(WorkflowStatesType::class, $workflow);

    // $firstFormPart->handleRequest($request);
    $firstFormPart->submit($request->get($firstFormPart->getName()), false);

    $secondFormPart = $this->createForm(WorkflowTransitionsType::class, $workflow);
    // secondFormPart is created correct with all values after submitting $firstFormPart and calling submit

    if($firstFormPart->isSubmitted() && $firstFormPart->isValid()) {
        return $this->render('@MyBundle/Workflow/workflow_edit_create_second_part.html.twig', array(
            'form'   => $secondFormPart->createView(),
        ));
        // This will render correctly with all values submitted in the $firstFormPart
    }

    $secondFormPart->submit($request->get($secondFormPart->getName()), false);
    // $secondFormPart->handleRequest($request);
    // HERE IS THE PROBLEM -> After submitting the $secondFormPart all property values set in the $firstFormPart are gone

    if($secondFormPart->isSubmitted() && $secondFormPart->isValid()) {
        dump($workflow);
        die();
    }

    return $this->render('@MyBundle/Workflow/workflow_edit_create_first_part.html.twig', array(
        'form' => $firstFormPart->createView(),
    ));
}


WorkflowStatesType :

class WorkflowStatesType extends AbstractType {

        /**
         * @var \Doctrine\ORM\Mapping\ClassMetadata
         */
        private $classMetadata;

        /**
         * WorkflowType constructor.
         * @param EntityManager $em
         */

        public function __construct(EntityManager $em) {
            $this->classMetadata = $em->getClassMetadata(Workflow::class);
        }

        public function buildForm(FormBuilderInterface $builder, array $options) {
            $builder
                ->setMethod('PATCH')
                ->add('name', TextType::class, array(
                    'label' => 'nameTrans',
                    'attr'  => array('maxLength' => $this->classMetadata->getFieldMapping('name')['length']),
                ))
                ->add('states',  CollectionType::class, array(
                    'entry_type'        => StateType::class,
                    'allow_add'         => true,
                    'error_bubbling'    => false,
                    'by_reference'      => false,
                    'label'             => 'workflowStatesTrans',
                ))
                ->add('next', SubmitType::class, array(
                    'label' => 'nextFormPartTrans',
                ));
        }

        public function configureOptions(OptionsResolver $resolver) {
            $resolver->setDefaults(array(
                'data_class'            => Workflow::class,
                'translation_domain'    => 'My_Bundle',
            ));
        }

    }


WorkflowTransitionsType :

class WorkflowTransitionsType extends AbstractType {

        /**
         * @var Workflow
         */
        private $workflow;

        /**
         * @var Session
         */
        private $session;

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

            /** @var Workflow $workflow */
            $this->workflow = $options['data'];

                $builder
                    ->setMethod('PATCH')
                    ->add('initialState', ChoiceType::class, array(
                        'choices'           => $this->workflow->getStates(),
                        'choice_label'      => function($state) {
                            return ($state && $state instanceof State) ? $state->getStatekey() : 'noVal';
                        },
                        'choice_value'      => function($state) {
                            return ($state && $state instanceof State) ? $state->getStatekey() : 'noVal';
                        },

                        // This combination of 'expanded' and 'multiple' implements a select box
                        'expanded'          => false,
                        'multiple'          => false,
                    ))
                    ->add('transitions', CollectionType::class, array(
                        'entry_type'        => TransitionType::class,
                        'allow_add'         => true,
                        'allow_delete'      => true,
                        'error_bubbling'    => false,
                        'by_reference'      => false,
                        'label'             => 'transitionsTrans',
                        'entry_options'     => array(
                            'states'    => $this->workflow->getStates(),
                        ),
                    ))
                    ->add('save', SubmitType::class, array(
                        'label'             => 'submitTrans',
                    ));
        }

        public function configureOptions(OptionsResolver $resolver) {
            $resolver->setDefaults(array(
                'data_class'            => Workflow::class,
                'translation_domain'    => 'My_Bundle',
            ));
            $resolver->setRequired(array(
                'session'
            ));
        }
    }

在提交 $ secondFormPart 时,如何保存在 $ firstFormPart 中提交的 $ workflow 的属性值?

How can I hold the property values of the $workflow submitted in the $firstFormPart when submitting the $secondFormPart?

推荐答案

因为仅使用secondForm数据再次提交了表单,所以您丢失了firstForm数据.

Because the form is submitted again with only the secondForm data, you are losing the firstForm data.

您可以通过3种方式保留它们:

You have 3 ways to keep them:

1)将firstForm中的数据设置到查询中

// Insert that instead of the `return $this->render` for the second form
$url = $this->generateUrl(
    $request->attributes->get('_route'),
    array_merge(
        $request->query->all(),
        array('secondForm' => true, 'name' => $workflow->getName(), 'states' => $workflow->getStates()) // change the param
    )
);
return $this->redirect($url);

$ secondFormPart = $ this-> createForm(WorkflowTransitionsType :: class,$ workflow);

name states 设置回 $ workflow 实体,在此示例中,您可以检查查询变量 secondForm 了解是否已提交第一个表格

Set back the name and states into the $workflow entity, in this example you can check the query variable secondForm to know if the first form was submitted or not

2)将具有某些隐藏字段的数据从firstForm设置到下一个PATCH请求中

您必须修改secondForm以使用一些

You have to modify the secondForm to handle the data from the firstForm with some hidden form type

3)在返回第二个表单之前在会话中设置数据

首先,您的实体将必须实现接口 Serializable 并声明方法 serialize unserialize

First of all, your entity will have to implement the interface Serializable and declare the method serialize and unserialize

喜欢

$this->get('session')->set('workflow', $workflow);

将使用方法 serialize 进行存储.

您可以使用方法 unserialize

$session = $this->get('session');
$workflow = new Workflow();
$workflow->unserialize($session->get('workflow'));

由于要将整个实体存储到会话中,因此该解决方案将大大降低应用程序的性能

Because you are storing the whole entity into the session, this solution will decrease a lot the performance of your application

这篇关于Symfony 3-表单模型数据丢失了属性值,这些属性值未由字段表示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆