Symfony 3.3 - 具有太多数据的ChoiceType的替代方案

时间:2018-02-24 04:29:41

标签: php symfony

我有一个我正在创建的表单,我希望用户能够从值列表中选择(使用ChoiceType),尽管此列表超过100k值(带有名称和ID)。正如预期的那样,这是太多的数据并导致浏览器在DOM中使用这么多数据。有关如何解决这个问题的任何想法?

我有一个想法是做一个提前输入搜索功能并将id存储到隐藏值中,虽然我想看看这里的Symfony专家是否有更好的想法。

谢谢!

2 个答案:

答案 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 建立了一个小项目,所以如果我的约定稍微偏离,我会道歉(版本 - 明智的)。