创建一个“ Ajaxified”表单字段类型 [英] Creating a 'Ajaxified' Form Field Type
问题描述
在我的应用程序中,我有几个带有许多选项的表单字段。我遇到的问题类似于此问题:每次页面加载时获取和解析所有选项的成本很高(Twig会一遍又一遍地渲染所有选项,而无法进行客户端缓存)。这个问题使我创造了一种通过AJAX将选项发送到浏览器的方法。相当简单的方法:
In my application I've got a couple of form fields with many options. The problem I experienced is similar to this question: getting and parsing all options at every page load is expensive (Twig renders all options over and over again while no client side caching possible). That problem made me create a way to send the options via AJAX to the browser. Fairly simple approach:
- 通过AJAX(例如,通过获取/countries.json)获取所有选项(键值)并在可能的情况下进行缓存。 (在这种情况下,国家名称不太可能经常更改)
- 使用selectize,select2或类似插件将选项插入DOM。
- 享受更快的表单:-)
防止Symfony查询所有选项(不必要:它们是通过AJAX加载的)加载表单时,我在 QueryBuilder
中添加了 setMaxResults(0)
(通过控制器添加选项)。是的,那太过分了。提交表单时,它仍然会执行查询,因为它必须验证所选选项是否存在(并检查约束)。
To prevent Symfony from querying all options (not necessary: they're loading via AJAX) I added setMaxResults(0)
to the QueryBuilder
when the form is loaded (by adding an option via the controller). Yes, that's kludge. When submitting a form it will still perform a query, because it has to verify if the selected option exists (and check for Constraints).
我想创建一个<一个href = http://symfony.com/doc/current/cookbook/form/create_custom_field_type.html rel = nofollow noreferrer>自定义表单字段类型,它将此功能添加到当前的 EntityType
:在呈现表单时不加载选项,但仍检查所选选项是否存在。我发现很多 示例与动态修改表单,但是我还没有找到与仅修改一个表单域相关的示例,而与它的父表单无关。
I would like to create a custom Form Field Type that adds this functionality to the current EntityType
: don't load the options while rendering the form, but still check if the selected option exists. I found many examples related to dynamically modifying a form, but I haven't found examples related to modifying just one form field, independently of it's parent form.
如何创建这样的表单字段类型?好的起点是什么?扩展 EntityType
, ChoiceType
还是其他方法?
How do I create a form field type like this? What's a good starting point? Extend EntityType
, ChoiceType
or an other approach?
我已经在使用Symfony 3.1,所以使用懒惰地加载表单选择(Symfony 3.2中的新功能)不会有问题。不知道此新功能是否与我的问题有关。
I'm already using Symfony 3.1, so using lazy loading of form choices (New in Symfony 3.2) won't be a problem. Not sure if this new feature is related to my problem.
推荐答案
我写了一个捆绑包( Alsatian / FormBundle ),它可以在服务器端实现您想要的功能。
I wrote a bundle (Alsatian/FormBundle), which does what you want on the server side.
abstract class AbstractExtensibleChoicesType extends AbstractRoutableType
{
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('choices',array());
}
}
如何使用缓存填充表单字段内容:
How to populate the form field with cached content :
这是您自己的逻辑,我建议:创建一个仅返回(作为HTML)的控制器:
That's your own logic, I would suggest : create a controller which only returns (as HTML) :
<option value="1">Option 1</option>
<option value="2">Option 2</option>
在控制器集中Maxage:
In the controller set Maxage :
/*
* @Route(...)
* @Cache(maxage=64000)
*/
public function getOptionsAction(Request $request) // Home
{
$choices = $this->getDoctrine()->getManager()->getRepository //....
return $this->render(/*...*/);
}
使用javascript加载此url并将html结果放入您的选择字段
Use javascript to load this url and to put the html result in your select field.
如果您使用的是Select2之类的东西:
您的控制器还可以将选项作为JSONReponse()返回,那么您可以直接从select2 ajax选项(请参阅捆绑文档,这就是我的用法)。
If you are using something like Select2 : Your Controller can also return the options as a JSONReponse(), then you can load this JSON directly from the select2 ajax option (see bundle documentation, that's how I use it).
- 最困难的是:如何使提交的选择有效:
- And the most difficult : How to make the submitted choice valid :
在Form :: PRE_SUBMIT事件中获取建议的选择(如果使用表单进行编辑,也请输入PRE_SET_DATA),然后将这些选择重新注入字段。
Get the sumitted choices in a Form::PRE_SUBMIT event (also PRE_SET_DATA if you use your form to edit), and reinject these choices to the field.
这篇关于创建一个“ Ajaxified”表单字段类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!