[英]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.