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

时间:2013-04-16 15:29:48

标签: forms object select symfony doctrine

我有问题。一开始,这是我创建形式的行为:

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

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

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

'Zlecenie'对象具有'Kategoria'类型的'Kategoria'字段(来自关系)。

持久化实体的方法:

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(),
    );
}

并形成课程:

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

通常情况下,我可以添加以下字段:

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

并从列表中选择Kategoria。

但问题是:我不想从选择列表或复选框列表中选择Kategoria。我想使用预定义的$ kategoria对象。当然(如果必须存在)'Kategoria'字段必须隐藏。我怎么能这样做?

2 个答案:

答案 0 :(得分:1)

您可以创建一个数据转换器,将表单中用户输入的数据转换为其他内容。 在您的情况下,您将把用户提交的Kategoria ID转换为Kategoria对象。这里最好的选择是定义表单中的“Kategoria”属性是隐藏的表单类型。 呈现表单时,您将隐藏一个输入,该输入将存储您的Kategoria对象的ID。当表单被提交时,变换器将该ID反转到对应的Kategoria对象。如果要在创建Klient对象后在控制器中定义默认的Kategoria,则应设置Kategoria。

如果你按照这个来源http://symfony.com/doc/master/cookbook/form/data_transformers.html,一切都会好起来的。任何问题只是说

答案 1 :(得分:1)

试试这个,调整到你的目录结构: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' )
                }
                ;
            }

变压器:

    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;
        }
    }