我以ChoiceType
这种方式使用了字段。我认为这是合乎逻辑的选择。它的主要问题(以及默认的EntityToIdTransformer
or EntityChoiceList
)是它为每个可能的选项提供了水合物以便选择一个,这在某些情况下是矫枉过正的。您可能需要编写自己的转换器来防止这种情况。我在页面加载后使用 AJAX 将数据加载到选择中。它使页面更小,加快页面处理时间,并让我更精确地缓存每组选项。
这是针对 Symfony 2.0 的。它工作正常,我们在一个页面上放置了一堆选择的字段,其中包含 4000 多个选项(尽管它仅在用户与小部件交互时创建选择的元素)。现在限制是浏览器内存。
联系实体类型
class ContactEntityType extends AbstractType {
public function __construct(EntityManager $em) {
$this->em = $em;
}
public function buildForm(FormBuilder $builder, array $options)
{
$repository = $this->em->getRepository('AcmeContactsBundle:Contact');
$builder->prependClientTransformer(new ContactToIdTransformer($repository));
}
public function buildView(FormView $view, FormInterface $form)
{
$contact = $form->getData();
if($contact instanceof \Acme\ContactsBundle\Entity\Contact) {
$view->set('choices', array($contact->getId() => $contact->getName()));
}
}
public function getParent(array $options) {
return 'choice';
}
}
ContactToIdTransformer
这是内置EntityToIdTransformer
.
...
class ContactToIdTransformer implements DataTransformerInterface
{
private $repository;
public function __construct(EntityRepository $repository)
{
$this->repository = $repository;
}
public function transform($entity)
{
if (null === $entity || '' === $entity) {
return null;
}
if (!is_object($entity)) {
throw new UnexpectedTypeException($entity, 'object');
}
if ($entity instanceof Collection) {
throw new \InvalidArgumentException('Expected an object, but got a collection. Did you forget to pass "multiple=true" to an entity field?');
}
return $entity->getId();
}
public function reverseTransform($key)
{
if ('' === $key || null === $key) {
return null;
}
if (!is_numeric($key)) {
throw new UnexpectedTypeException($key, 'numeric');
}
if (!($entity = $this->repository->find($key))) {
throw new TransformationFailedException(sprintf('The entity with key "%s" could not be found', $key));
}
return $entity;
}
}