简体   繁体   English

如何在Symfony2中传递带有表单的对象

[英]How to pass an object with form in Symfony2

I have a problem. 我有个问题。 At the beginning, this is my action which create form: 一开始,这是我创建形式的动作:

public function wyswietlDostepneTerminyAction($kategoria) {
    $zlecenie = new Zlecenia();

    $form = $this->createForm(new ZleceniaAddType(), $zlecenie);

    return array ('form' => $form->createView(), 'kategoria'=>$kategoria);
}

'Zlecenie' object has 'Kategoria' field of 'Kategorie' type (its from relation). 'Zlecenie'对象具有'Kategoria'类型的'Kategoria'字段(来自关系)。

Method which persist entity: 持久化实体的方法:

public function noweZlecenieAction(Request $request) {
    $entity  = new Zlecenia();
    $form = $this->createForm(new ZleceniaAddType(), $entity);
    $form->bind($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($entity);
        $em->flush();

        return $this->redirect($this->generateUrl('pokaz-zlecenie', array('id' => $entity->getId())));
    }

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

And form class: 和表格类:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('opis')
        ->add('klient', new KlientType())
        //->add('kategoria')
    ;
}

Normally, I can add field like: 通常,我可以添加如下字段:

->add('kategoria','entity', array('class'=>'Acme\MyBundle\Entity\Zlecenia')

and select Kategoria from list. 并从列表中选择Kategoria。

But the problem is: I don't want to choose Kategoria from select list or checkbox list. 但问题是:我不想从选择列表或复选框列表中选择Kategoria。 I want to use predefined $kategoria object. 我想使用预定义的$ kategoria对象。 Of course (if must exist) 'Kategoria' field must be hidden. 当然(如果必须存在)'Kategoria'字段必须隐藏。 How can I do that? 我怎样才能做到这一点?

You can create a data transformer that will transform the data entered by the user in a form into something else. 您可以创建一个数据转换器,将表单中用户输入的数据转换为其他内容。 In your case you will transform a Kategoria ID submited by the user into Kategoria object. 在您的情况下,您将把用户提交的Kategoria ID转换为Kategoria对象。 The best option for you here is define that your "Kategoria" property in your form will be of hidden form type. 这里最好的选择是定义表单中的“Kategoria”属性是隐藏的表单类型。 When the form is rendered you will have a input hidden that will store the ID of your Kategoria object. 呈现表单时,您将隐藏一个输入,该输入将存储您的Kategoria对象的ID。 When the form is submited the transformer will reverse that ID to the correspondent Kategoria Object. 当表单被提交时,变换器将该ID反转到对应的Kategoria对象。 As you want to define a default Kategoria, in your controller after you create the Klient object you should set the Kategoria. 如果要在创建Klient对象后在控制器中定义默认的Kategoria,则应设置Kategoria。

If you follow this source http://symfony.com/doc/master/cookbook/form/data_transformers.html , everything will went fine. 如果你按照这个来源http://symfony.com/doc/master/cookbook/form/data_transformers.html ,一切都会好起来的。 Any questions just say 有问题的话

Try this, tweaking to your directory structure: Formtype: 试试这个,调整到你的目录结构:Formtype:

    public function buildForm( FormBuilderInterface $builder, array $options ) {
        if ( isset( $options['attr']['kategoria'] ) ) {
            $kategoria = $options['attr']['kategoria'];
        }
        else {$kategoria=null;}
        $builder
        ->add( 'opis' )
        ->add( 'klient', new KlientType() );
        if ( $kategoria ) {
            $transformer = new KategoriaTransformer( $em );
            $builder->add(
                $builder->create( 'kategoria'
                    ->add( 'kategoria', 'hidden', array()
                    )
                )
                ->addModelTransformer( $transformer );
            }  else {
                ->add( 'kategoria', 'entity'
                     , array( 'class'=>'Acme\MyBundle\Entity\Zlecenia' )
                }
                ;
            }

And the transformer: 和变压器:

    namespace Acme\MyBundle\Entity\Zlecenia\Transformer;

    use Doctrine\Common\Persistence\ObjectManager;
    use Symfony\Component\Form\DataTransformerInterface;
    use Symfony\Component\Form\Exception\TransformationFailedException;

    class kategoriaTransformer implements DataTransformerInterface
    {
        /**
        * @var ObjectManager
        */
        private $em;

        /**
        * @param ObjectManager $em
        */
        public function __construct(ObjectManager $em)
        {
            $this->em = $em;
        }

        /**
        * Transforms an object (kategoria) to a string (id).
        *
        * @param  Issue|null $kategoria
        * @return string
        */
        public function transform($kategoria)
        {
            if (null === $kategoria) {return "";}
            if (is_object($kategoria) && 
                method_exists($kategoria, "toArray")){
                $kategoria=$kategoria->map(function ($ob){
                     return $ob->getId();});
                return implode(",",$kategoria->toArray());
            }
            return $kategoria->getId();
        }

        /**
        * Transforms a string (id) to an object (kategoria).
        *
        * @param  string $id
        * @return Issue|null
        * @throws TransformationFailedException 
        *         if object (kategoria) is not found.
        */
        public function reverseTransform($id)
        {
            if (!$id) {
                if($this->multi) {return array();}
                return null;
            }

            if (strpos($id,',') !== false) {
                $id=explode(',',$id);
            }
            $qb=$this->em->getRepository(
            'Acme\MyBundle\Entity\Zlecenia\Repository\kategoria'
            )
            ->createQueryBuilder('k');
            $qb->andWhere($qb->expr()->in('i.id', $id));
            if (is_array($id) || $this->multi){
                $kategoria=$qb->getQuery()
                ->getResult();
            } else {
                $kategoria=$qb->getQuery()
                ->getSingleResult();
            }
            if (null === $kategoria) {
                throw new TransformationFailedException(sprintf(
                    'A kategoria with id "%s" does not exist!',
                    $id
                    ));
            }

            return $kategoria;
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM