Forms 如何在Symfony2中传递形式为的对象

Forms 如何在Symfony2中传递形式为的对象,forms,object,select,symfony,doctrine,Forms,Object,Select,Symfony,Doctrine,我有个问题。首先,这是我创建表单的操作: public function wyswietlDostepneTerminyAction($kategoria) { $zlecenie = new Zlecenia(); $form = $this->createForm(new ZleceniaAddType(), $zlecenie); return array ('form' => $form->createView(), 'kategoria'=

我有个问题。首先,这是我创建表单的操作:

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

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

    return array ('form' => $form->createView(), 'kategoria'=>$kategoria);
}
“Zlecenie”对象具有“Kategorie”类型的“Kategoria”字段(其from关系)

保存实体的方法:

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'字段必须隐藏。我该怎么做呢?

您可以创建一个数据转换器,将用户在表单中输入的数据转换为其他数据。 在本例中,您将把用户提交的Kategoria ID转换为Kategoria对象。在这里,您最好的选择是定义表单中的“Kategoria”属性为隐藏表单类型。 呈现表单时,您将隐藏一个输入,该输入将存储Kategoria对象的ID。提交表单时,transformer会将该ID反转为相应的Kategoria对象。由于要定义默认的Kategoria,在创建Klient对象后,应在控制器中设置Kategoria


如果你遵循这个来源,一切都会好起来的。任何问题只要说

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

这正是我要找的!非常感谢。:)