个性化阅读
专注于IT技术分析

如何在你的Symfony 3表单中检索未映射字段的值

如果你在Symfony中使用表单, 那么你将知道为任何实体实现新的Type多么容易, 因此你可以在应用程序中轻松创建CRUD表单操作。有时, 你可能希望从控制器向表单中添加动态字段, 因为你不希望此字段出现在另一个字段中, 因为在这种情况下只需要它。这可以通过表单字段的映射属性来实现。

假设我们有一个UserType来创建一个Form来在我们的应用程序中注册用户:

<?php

namespace userBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;


class UserType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class , array(
                "attr" => array(
                    "class" => "form-control"
                )
            ))
            ->add('username', TextType::class, array(
                "attr" => array(
                    "class" => "form-control"
                )
            ))
            ->add('description', TextareaType::class, array(
                "attr" => array(
                    "class" => "form-control", "maxlength" => 255
                )
            ))
            ->add('password', RepeatedType::class, array(
                'type' => PasswordType::class, 'invalid_message' => 'The password fields must match.', 'options' => array(
                    'attr' => array(
                        'class' => 'form-control'
                    )
                ), 'required' => true, 'first_options'  => array('label' => 'Password'), 'second_options' => array('label' => 'Repeat Password'), ))
        ;
    }
    
    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'userBundle\Entity\User'
        ));
    }

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

此类型包含5个来自UserEntity的必填字段, 将在我们的控制器中进行处理以创建新用户。在控制器的newAction中, 我们将使用以下代码创建一个表单:

<?php

public function newuserAction(Request $request){
    $user = new User();
    
    // Create a form using the UserType
    $form = $this->createForm(UserType::class, $user);
    
    // Add dinamically a new multiple select field that isn't in the UserEntity:
    $form->add('roles_options', ChoiceType::class, array(
        "mapped" => false, "multiple" => true, "attr" => array(
            'class' => "form-control"
        ), 'choices'  => array(
            'Blogger' => 'ROLE_BLOGGER', 'Administrator' => 'ROLE_ADMIN'
        )
    ));

    $form->handleRequest($request);

    if ($form->isSubmitted()) {
        // Rest of the logic
    }

    return $this->render('users/new.html.twig', array(
        'form' => $form->createView()
    ));
}

现在, 如果用户访问新路线, 他将看到只需要提交的表单。提交后, 将触发相同的newAction(如果在POST中的routing.yml中进行了配置), 则将执行处理表单的逻辑。创建具有Symfony类型的表单的优点是你可以轻松地将实体持久保存在控制器中, 但是有时你需要通过修改某些值(或将其用于其他目的)使控制器中的处理步骤动态化, 以便使用表单的getData方法可以轻松地检索表单的值:

<?php

if ($form->isSubmitted()) {
    $data = $form->getData();
    
    // $data  contains an array like:
    // array(
    //    "name" => "The submitted name", //    "username" => "The submitted Username", //    "description" => "The submitted description", //    "password" => "The submitted password"
    // );
}

但是, 等等, ****是我们在控制器中动态添加的role_options字段的值?它不在真实形式之内, 只是因为该字段未映射, 所以它不能在真实形式之内, 因为这会触发另一个异常, 即”此形式不应包含额外的字段”。

检索非映射字段的值

而不是访问表单数组数据中的值, 你需要使用表单中的get方法, 该方法将未映射字段的名称作为第一个参数。从返回的对象中, 可以使用getData方法检索值:

<?php

if ($form->isSubmitted()) {
    $data = $form->getData();

    // Retrieve the value from the extra field non-mapped !
    $roles = $form->get("roles_options")->getData();

    // Where $data  contains an array like:
    // array(
    //    "name" => "The submitted name", //    "username" => "The submitted Username", //    "description" => "The submitted description", //    "password" => "The submitted password"
    // );

    // and $roles another array in this case with our options (that were selected obviously):
    // [
    //   0 => "ROLE_BLOGGER"
    //   1 => "ROLE_ADMIN"
    // ]
}

编码愉快!

赞(0)
未经允许不得转载:srcmini » 如何在你的Symfony 3表单中检索未映射字段的值

评论 抢沙发

评论前必须登录!