2

这是我在 SF2 上的第一步。我想在包含其他实体的实体上设置多步骤表单。

我有一个表单类型(缩短)

class ApplicationFormType extends AbstractType
{
    protected $_step = 1;

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        if ($this->_step == 1) {
            $builder
                ->add('patient', new Type\PersonType())
                ->add('insurance', 'entity', array(
                    'class' => 'Acme\MainBundle\Entity\Insurance',
                ));
        } elseif ($this->_step == 2) {
            $nurse = new Type\PersonType();
            $nurse->requireBareData();
            $builder
                ->add('nurse', $nurse)
                ->add('nurse_type', 'entity', array(
                    'class' => 'Acme\MainBundle\Entity\NurseType',
                    'expanded' => true,
                    'multiple' => false,
                ))
                ->add('nursing_support', 'checkbox', array(
                    'required' => false,
                ));
        }
    }

    public function setStep($step)
    {
        $this->_step = $step;
    }

我的控制器看起来像

public function assistAction() {
    $request = $this->getRequest();

    $step = $this->getSession()->get('assist_step', 1);
    if ($request->getMethod() != 'POST') {
        $step = 1;
        $this->getSession()->set('assist_data', NULL);
    }
    $this->getSession()->set('assist_step', $step);
    $application = new Application();
    $type = new ApplicationFormType();
    $type->setStep($step);

    $form = $this->createForm($type, $application, array(
        'validation_groups' => array($step == 1 ? 'FormStepOne' : 'FormStepTwo'),
    ));
    if ($request->getMethod() == 'POST') {
        $form->bindRequest($request);
        if ($form->isValid()) {
            if ($step == 1) {

                $data = $form->getData();
                $this->getSession()->set('assist_data', serialize($data));
                $this->getSession()->set('assist_step', ++$step);
                $type = new ApplicationFormType();
                $type->setStep($step);
                $form = $this->createForm($type, $application, array(
                    'validation_groups' => array('FormStepTwo'),
                ));

            } else {

                $step_1 = unserialize($this->getSession()->get('assist_data', ''));
                $data = $form->getData();
=>                $data->setPatient($step_1->getPatient());
=>                $data->setInsurance($step_1->getInsurance());
                $this->getSession()->set('assist_data', NULL);
                $this->getSession()->set('assist_step', 1);

            }
        }
    }

    return $this->render('Acme:Default:onlineassist.html.twig', array(
        'form' => $form->createView(),
        'step' => $step,
    ));
}

我的问题是,如果我必须单独“复制”第一个表单步骤的属性,例如:

$data->setPatient($step_1->getPatient());
$data->setInsurance($step_1->getInsurance());

或者我可以将会话中的未序列化数据与第二个表单步骤中的数据合并吗?还是有完全不同的方法?

4

2 回答 2

1

实体可以根据stackoverflow上的响应进行序列化并放入会话中。

如果每个表单都是不同的类型,我建议您将类型分解为多种类型。

这是我的设想:

public function submitAction($step = 1)
{
    switch ($step) {
        case 1:
            $entity = new EntityOne();
            $form = $this->createForm(new EntityOneType(), $entity);
            $template = "template_one.html.twig";
            $redirect = $urlToStepTwo; // which redirects to this controller action with $step = 2
            break;
        case 2:
            $entity = new EntityTwo();
            $form = $this->createForm(new EntityTwoType(), $entity);
            $template = "template_two.html.twig";
            $redirect = $urlToStepThree; // which redirects to this controller action with $step = 3
            break;
        case 3:
            $entity = new EntityThird();
            $form = $this->createForm(new EntityThreeType(), $entity);
            $template = "template_three.html.twig";
            $redirect = $urlToConfirmPage; // which redirects to another controller action that unserialize all entities and save them in the DB
            break;
        default:
            throw $this->createNotFoundException();
            break;
    }

    $request = $this->get('request');
    $session = $this->get('session');

    if ($request->isMethod('post') === true) {

        $form->bind($request);

        if ($form->isValid() === true) {
            $session->set('entity_'. $step, serialize($entity));

            return $this->redirect($redirect);
        }
    }

    $params = array(
        'form'    => $form->createView(),
        'entity'  => $entity
    );

    return $this->render($template, $params);
}
于 2013-03-20T16:38:56.547 回答
0

好的,除了单独设置前置步骤字段之外别无他法,比如

$pre_step = unserialize($this->getSession()->get('assist_data', ''));
$data->setPatient($pre_step->getPatient());
$data->setInsurance($pre_step->getInsurance());
$data->setInsuranceNumber($pre_step->getInsuranceNumber());
$data->setInsuranceLevel($pre_step->getInsuranceLevel());

这就是我迄今为止所做的。

于 2013-03-28T16:07:39.263 回答