有没有办法在Symfony中获取EntityType
表单元素,它不会预加载所有条目,但仍接受它们?
背景:它适用于图像选择器,可能会存储1000多张图像。每次渲染字段时,我都不想在DB上加载。表单有一个自定义前端,使用隐藏字段和Javascript(加载分页的图像列表)。
当前的实现工作正常,但是当它扩展EntityType
时它会完成所有预加载,而当使用ChoiceType
时,表单不接受这些值(除非,你给他们作为选择,这意味着加载来自DB的所有条目
-----------------------编辑-----------------------
我正在使用建议的bundle。如果您觉得需要像我一样拥有自己的视图(小部件),那么您可以轻松实现这一目标:
如果您使用composer,则可以简单地安装所有运行所需的文件
composer require alsatian/form-bundle dev-master
安装捆绑包后,您可以按照以下步骤操作:
首先,你必须创建自己的表单字段(我的看起来像这样):
<?php
namespace AppBundle\Form\Fields;
use Symfony\Component\Form\AbstractType;
use Alsatian\FormBundle\Form\ExtensibleEntityType;
class UploadFileType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function getParent() {
return ExtensibleEntityType::class;
}
/**
* {@inheritdoc}
*/
public function getName() {
return 'app_upload_file';
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'app_upload_file';
}
}
注意:您可以在getBlockPrefix
中添加任何内容,只需记住您放置的内容。
接下来,您需要修改表单主题(doc)并添加自己的小部件:
{%- block app_upload_file_widget -%}
{{ dump(form) }}{# output some debug info #}
{% if not expanded %}
{# example for some fake entries #}
{% if multiple %}
<input type="hidden" name="{{ full_name }}" value="1" />
<input type="hidden" name="{{ full_name }}" value="2" />
<input type="hidden" name="{{ full_name }}" value="3" />
{% else %}
<input type="hidden" name="{{ full_name }}" value="1" />
{% endif %}
{% else %}
{{- block('choice_widget') -}}
{% endif %}
{%- endblock app_upload_file_widget -%}
注意:我们需要getBlockPrefix
,只需添加_widget
即可!
最后,我们可以将其添加到我们的一种表单中:
<?php
namespace AppBundle\Form\Admin;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class CompanyType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('logo', \AppBundle\Form\Fields\UploadFileType::class, array(
'class' => \AppBundle\Entity\File::class,
'choice_label' => 'originalName',
))
;
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Company'
));
}
}
当然我们需要在我们的实体中加入,对我来说,它看起来像这样:
/**
* @ORM\ManyToOne(targetEntity="File")
* @ORM\JoinColumn(name="logo_id", referencedColumnName="id")
*/
private $logo;
我希望,这有助于某人,这与我的情况相同(:
答案 0 :(得分:1)
这个问题每3天发出一次:)
我从here粘贴我的答案:
我写了一个包(Alsatian/FormBundle),它可以在服务器端执行您想要的操作。
How to avoid loading each entities by each form rendering:
abstract class AbstractExtensibleChoicesType extends AbstractRoutableType
{
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('choices',array());
}
}
在Form :: PRE_SUBMIT事件中获取总结选项(如果使用表单进行编辑,也可以使用PRE_SET_DATA),并将这些选项重新输入到字段中。