簡體   English   中英

Symfony2 DataTransformer用於選擇字段

[英]Symfony2 DataTransformer for choice field

我正在嘗試創建自定義選項列表字段。 除了編輯部分上的預選值外,幾乎所有內容似乎都有效。

基本上我正在創建一個具有多個對象類型的混合列表字段(后端是mongodb),我知道這是一種骯臟的操作方式,但我找不到更好的解決方案(保持簡單)。 這個過程正常,我在后端有一個混合對象,我可以在編輯表單中選擇哪一個,但是表單沒有顯示預選(使用從mongo中提取的值)

<?php
namespace www\DefaultBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use www\DefaultBundle\Form\DataTransformer\AccessorioTransformer;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class AccessorioType extends AbstractType
{
    /**
     * @var ObjectManager
     */
    private $om;

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


    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $transformer = new AccessorioTransformer($this->om);
        $builder->addModelTransformer($transformer);
    }


    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $choices = array();
        $data = array();
        $documents = array(
            'Document1',
            'Document2',
            'Document3',
            );

        foreach ($documents as $document)
        {
            $objects = $this->om->getRepository('wwwDefaultBundle:' . $document)->findAll();
            foreach ($objects as $object)
            {
               if (@!$object->getId()) print_r($object);
               $key = sprintf("%s_%s", $object->getId(), basename(str_replace('\\', '/', get_class($object))));
               $value = sprintf("%s (%s)", $object, basename(str_replace('\\', '/', get_class($object))));
               $choices[$key] = $value;
            }
        }

        $resolver->setDefaults(array(
            'choices'  => $choices,
            'expanded' => false,
            'multiple' => true,
        ));

    }


    public function getParent()
    {
        return 'choice';
    }

    public function getName()
    {
        return 'accessorio';
    }
}

datatransformer:

<?php
namespace www\DefaultBundle\Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Extension\Core\ObjectChoiceList;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Doctrine\Common\Persistence\ObjectManager;
use Acme\TaskBundle\Entity\Issue;

class AccessorioTransformer implements DataTransformerInterface
{
    /**
     * @var ObjectManager
     */
    private $om;

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


    public function transform($values)
    {
        return array();
        // i tried everything here but none working

    }


    public function reverseTransform($values)
    {
        if (!$values) return null;

        $array = array();

        foreach ($values as $value)
        {
          list($id, $type) = explode("_", $value);
          $array[] = $this->om->getRepository('wwwDefaultBundle:' . $type)->find($id);
        }

        return $array;
    }
}

表單生成器:

<?php

namespace www\DefaultBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class ValvolaType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder

            // [snip]

            ->add('ref',
                'accessorio',
                array(
                    'label_attr' => array('class' => 'control-label col-sm-2'),
                    'attr'       => array('class' => 'form-control '),
                ))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'www\DefaultBundle\Document\Valvola',
            'attr'       => array('class' => 'press form-horizontal'),
        ));
    }

    public function getName()
    {
        return 'www_defaultbundle_valvolatype';
    }
}

有人遇到同樣的問題嗎? 如何改變“選擇”領域? 如何在同一個字段中管理混合對象? 有人可以賜教我嗎?

問候

我終於找到了解決方案。 罪魁禍首是數據變換器(我當然是:-))通過這種方式,表單顯示了預選值:

<?php
namespace www\DefaultBundle\Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Extension\Core\ObjectChoiceList;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Doctrine\Common\Persistence\ObjectManager;
use Acme\TaskBundle\Entity\Issue;

class AccessorioTransformer implements DataTransformerInterface
{
    /**
     * @var ObjectManager
     */
    private $om;

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


    public function transform($values)
    {
        if ($values === null) return array();

        $choices = array();
        foreach ($values as $object)
        {
           $choices[] = sprintf("%s_%s", $object->getId(), basename(str_replace('\\', '/', get_class($object))));
        }

        return $choices;
    }


    public function reverseTransform($values)
    {
        if (!$values) return array();

        $array = array();

        foreach ($values as $value)
        {
          list($id, $type) = explode("_", $value);
          $array[] = $this->om->getRepository('wwwDefaultBundle:' . $type)->find($id);
        }

        return $array;
    }
}

在大多數使用ChoiceType的情況下,transform函數返回的數組應僅包含ID。 例如:

public function transform($objectsArray)
{
    $choices = array();

    foreach ($objectsArray as $object)
    {
       $choices[] = $object->getId();
    }

    return $choices;
}

雖然它可能不是原帖的答案,但我很確定googlers到這里尋找這個提示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM