在我的应用程序中,我有几个带有许多选项的表单字段。我遇到的问题类似于此问题:在每次页面加载时获取和解析所有选项的成本很高(Twig一次又一次地渲染所有选项,而无法进行客户端缓存)。这个问题使我创造了一种通过AJAX将选项发送到浏览器的方法。相当简单的方法:
为了防止Symfony查询所有选项(不必要:它们是通过AJAX加载的),我在加载表单时(通过控制器添加选项)添加setMaxResults(0)到QueryBuilder。是的,那太过分了。提交表单时,它仍将执行查询,因为它必须验证所选选项是否存在(并检查约束)。
setMaxResults(0)
QueryBuilder
我想创建一个自定义的“表单字段类型”,将该功能添加到当前表单中EntityType:渲染表单时不要加载选项,但仍要检查所选选项是否存在。我发现了许多 与动态修改表单有关的示例,但我还没有发现与仅修改一个表单域(独立于其父表单)有关的示例。
EntityType
如何创建这样的表单字段类型?一个好的起点是什么?扩展EntityType,ChoiceType还是其他方法?
ChoiceType
我已经在使用Symfony 3.1,因此使用表格选项的延迟加载(Symfony 3.2中的新增功能)将不是问题。不知道此新功能是否与我的问题有关。
我写了一个包(Alsatian / FormBundle),它可以在服务器端实现您想要的功能。
abstract class AbstractExtensibleChoicesType extends AbstractRoutableType { public function configureOptions(OptionsResolver $resolver) { $resolver->setDefault('choices',array()); } }
我建议,这是您自己的逻辑:创建一个仅返回(作为HTML)的控制器:
<option value="1">Option 1</option> <option value="2">Option 2</option>
在控制器中设置Maxage:
/* * @Route(...) * @Cache(maxage=64000) */ public function getOptionsAction(Request $request) // Home { $choices = $this->getDoctrine()->getManager()->getRepository //.... return $this->render(/*...*/); }
使用javascript加载此URL,并将html结果放入您的选择字段。
如果您使用的是Select2之类的东西:您的控制器还可以将选项作为JSONReponse()返回,那么您可以直接从select2 ajax选项加载此JSON(请参阅包文档,这就是我的用法)。
在Form :: PRE_SUBMIT事件中获取汇总的选择(如果使用表单进行编辑,则也请获取PRE_SET_DATA),然后将这些选择重新注入到字段中。