我假设您在表单中使用类型entity
。它们非常沉重,因为首先所有实体都是作为对象提取的,然后简化为id => label
风格。
所以,你可以写自己的entityChoice
类型,它与id => label
-array作品(所以没有什么取为在弗里斯特地方的对象),并添加一个DataTransformer这种类型:
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use MyNamespace\EntityToIdTransformer;
class EntityChoiceType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addModelTransformer(new EntityToIdTransformer($options['repository']));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'empty_value' => false,
'empty_data' => null,
));
$resolver->setRequired(array(
'repository'
));
}
public function getParent()
{
return 'choice';
}
public function getName()
{
return 'entityChoice';
}
}
而作为DataTransformer:
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
class EntityToIdTransformer implements DataTransformerInterface
{
private $entityRepository;
public function __construct(EntityRepository $entityRepository)
{
$this->entityRepository = $entityRepository;
}
/**
* @param object|array $entity
* @return int|int[]
*
* @throws TransformationFailedException
*/
public function transform($entity)
{
if ($entity === null) {
return null;
}
elseif (is_array($entity) || $entity instanceof \Doctrine\ORM\PersistentCollection) {
$ids = array();
foreach ($entity as $subEntity) {
$ids[] = $subEntity->getId();
}
return $ids;
}
elseif (is_object($entity)) {
return $entity->getId();
}
throw new TransformationFailedException((is_object($entity)? get_class($entity) : '').'('.gettype($entity).') is not a valid class for EntityToIdTransformer');
}
/**
* @param int|array $id
* @return object|object[]
*
* @throws TransformationFailedException
*/
public function reverseTransform($id)
{
if ($id === null) {
return null;
}
elseif (is_numeric($id)) {
$entity = $this->entityRepository->findOneBy(array('id' => $id));
if ($entity === null) {
throw new TransformationFailedException('A '.$this->entityRepository->getClassName().' with id #'.$id.' does not exist!');
}
return $entity;
}
elseif (is_array($id)) {
if (empty($id)) {
return array();
}
$entities = $this->entityRepository->findBy(array('id' => $id)); // its array('id' => array(...)), resulting in many entities!!
if (count($id) != count($entities)) {
throw new TransformationFailedException('Some '.$this->entityRepository->getClassName().' with ids #'.implode(', ', $id).' do not exist!');
}
return $entities;
}
throw new TransformationFailedException(gettype($id).' is not a valid type for EntityToIdTransformer');
}
}
最后注册FormType作为新类型的service.yml
services:
myNamespace.form.type.entityChoice:
class: MyNamespace\EntityChoiceType
tags:
- { name: form.type, alias: entityChoice }
可以再用$repository
使用它在您形式
$formBuilder->add('appliance', 'entityChoice', array(
'label' => 'My Label',
'repository' => $repository,
'choices' => $repository->getLabelsById(),
'multiple' => false,
'required' => false,
'empty_value' => '(none)',
))
为您所需的存储库,并'choices'
为阵列的一个实例与id => label
来源
2014-10-07 11:15:46
SBH
不使用type'entity'只是'选择'用'id => label'写出[DataTransformers](http://symfony.com/doc/current/cookbook/form/data_transformers.html)。然后,您只需使用普通的值并且只在最后选择某些内容时将其转换为所需的实体 – SBH 2014-10-07 11:01:05