我有一个我正在创建的表单,我希望用户能够从值列表中选择(使用ChoiceType),尽管此列表超过100k值(带有名称和ID)。正如预期的那样,这是太多的数据并导致浏览器在DOM中使用这么多数据。有关如何解决这个问题的任何想法?
我有一个想法是做一个提前输入搜索功能并将id存储到隐藏值中,虽然我想看看这里的Symfony专家是否有更好的想法。
谢谢!
答案 0 :(得分:1)
也许你可以使用自动填充的文字输入?
答案 1 :(得分:1)
你有正确的想法,在你的formType类中,只需添加一个占位符选项,让你的js作为模板抓取(克隆,操作,追加)。在键入至少3个字符以限制响应时间和大小之前,不要触发AJAX事件。将结果存储在全局缓存对象变量中,并在发送请求之前先检查缓存。这样您就不会发送重复的请求。 下面是在twig模板中使用jQuery并假设你有一个这样注释的控制器方法的例子
/**
* @Route("api/search/{term}", defaults={"term"=null}, name="ajax_search_route_name")
*/
public function getInputChoices($term){
// do stuff
return new Symfony\Component\HttpFoundation\JsonResponse($choices);
}
带有搜索项的可选参数,因此twig path()函数将在加载时对基本路径起作用,搜索项将由js动态添加。
{% block javascripts %}
<script>
...
function triggerMeAfterTypingThreeOrMore(){
var input_val = $('#form_input_id).val();
var choices = (myCacheObject[input_val] != undefined) ?
myCacheObject[input_val] : false;
if(choices !== false){
// add cached choices to the dom
return;
}
// we only make it this far if there is no cache entry
getAutocompleteTerms(input_val);
}
function getAutocompleteTerms(input_val){
$.get({
url: "{{ path('ajax_search_route_name') }}" + "/" + input_val,
dataType: 'json',
success: function (data) {
//store the response locally, indexed by the search term
window.myCacheObject[input_val] = data;
},
complete: function (d) {
// retrigger to insert into dom
triggerMeAfterTypingThreeOrMore();
}
}
</script>
{% endblock javascripts %}
这种方式使用$.get
每个请求都会发送到不同的网址,例如"api/search/abc", "api/search/abcd"
,Symfony会处理服务器上的缓存响应。
我在Symfony 2 项目中使用此技术,其中包含非常大的数据和多个搜索字段,即使在1Mbps连接上也非常高效。我现在正处于Symfony 4 之中,我只用Symfony 3 建立了一个小项目,所以如果我的约定稍微偏离,我会道歉(版本 - 明智的)。