0

我有个问题。一开始,这是我创建表单的操作:

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

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

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

'Zlecenie' 对象具有 'Kategorie' 类型的 '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 对象。当然(如果必须存在)“类别”字段必须隐藏。我怎样才能做到这一点?

4

2 回答 2

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;
        }
    }
于 2013-04-16T17:07:40.857 回答
1

您可以创建一个数据转换器,将用户在表单中输入的数据转换为其他内容。在您的情况下,您会将用户提交的类别 ID 转换为类别对象。此处对您来说最好的选择是定义表单中的“类别”属性将是隐藏表单类型。呈现表单时,您将隐藏一个输入,该输入将存储您的类别对象的 ID。提交表单后,转换器会将该 ID 反转为对应的类别对象。由于您要定义默认类别,在您的控制器中创建 Klient 对象后,您应该设置类别。

如果您遵循此来源http://symfony.com/doc/master/cookbook/form/data_transformers.html,一切都会好起来的。有什么问题就说

于 2013-04-16T16:24:03.110 回答