【问题标题】:Typeahead in rails app: Append JSON request to only one specific request instead of appending JSON request to every request via prefetchRails 应用程序中的 Typeahead:仅将 JSON 请求附加到一个特定请求,而不是通过预取将 JSON 请求附加到每个请求
【发布时间】:2016-02-23 09:15:25
【问题描述】:

提前输入功能在它应有的地方工作。但问题是,提前输入功能会在每个数据请求上发出 JSON 请求,而实际上它应该只针对一个特定请求发生。

我有以下控制器:

#controllers/agencies_controller.rb
class AgenciesController < ApplicationController

  def get_unique_agency_names
    @unique_agency_names = Agency.uniq.pluck(:name)
    respond_to do |format|
      format.json { render json: @unique_agency_names }
    end
  end
  ...
end

我的 javascript 文件中有以下内容:

#app/assets/javascripts.agencies/index.js
$(document).ready(function(){
  /* For typeahead functionality on name input of search form for agencies */
  var agency_names = new Bloodhound({
    datumTokenizer: Bloodhound.tokenizers.whitespace,
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    prefetch: '../agencies/get_unique_agency_names.json'
  });

  $('#prefetch .typeahead.name_input').typeahead(null, {
    name: 'agency_names',
    source: agency_names
  });
});

为了完成,这里是我希望此功能发生的一个地方:以这种形式:

# just showing the relevant part of the form
<div class="form-group" id="prefetch">
  <%= f.label :name_cont, "Agency Name" %>
  <%= f.text_field :name_cont, class: "form-control typeahead name_input", placeholder: "Enter Agency Name" %>
</div>

这是我在config/routes.rb的相关路线

resources :agencies do
  collection do
    get 'get_unique_agency_names'
  end
end

我的具体问题是:如何确保仅在应该调用 GET "/agencies/get_unique_agency_names" 时才调用它?现在它正在为每个请求附加这个 JSON 请求。我只希望 JSON 请求针对一个特定请求发生。

Twitter's Type Ahead Examples

【问题讨论】:

  • 不就是 prefetch 的事情吗? “预取数据在初始化时被提取和处理。”
  • @DaveNewton 我正在考虑这个问题。我只是不确定我应该在它的位置放什么。
  • 不预取?仅在有意义的页面上预取? Bloodhound 存储库列出了您可以使用的预取选项。如果它出现在每个请求中,则意味着即使在无关紧要的页面上也包含此 JS,并且非绝对 URL 意味着它将将该 URL 附加到您所在的任何页面。

标签: javascript ruby-on-rails ruby json twitter-typeahead


【解决方案1】:

我会建议一种“限制”请求的策略,而不是以编程方式强制执行单个请求,因为您似乎正在处理一个大型数据集。您可以设置 Bloodhound 的 prefetch 选项以缓存您可以缓存的内容,并设置 sufficientremote 选项以确保对您的 JSON 文件的请求被回填和速率限制。为 Typeahead 的 minLength 选项设置一个更高的值作为最后一道防线。

Prefetch 会在一定程度上为您服务,因为它依赖于浏览器的本地缓存来进行缓存,而缓存容量有限。如果你的数据集很大,它只会缓存一部分,初始化后需要进一步的请求。

Remote 在初始化后处理请求,并且可以为您消除或限制这些请求,从而减少发出的请求数量。请参阅urlrateLimitByrateLimitWait 选项,它们可以作为散列分配给remote。此外,如果您的sufficient 基准数未达到,Bloodhound 将使用remote 回填其他基准。

最后,不要传递 null 并将 minLength 选项设置为高于您的 Typeahead 构造函数的默认值 1。这将防止对您的数据集进行过多的查找。只需确保 minLength 值小于您可能的最小结果的长度即可。

【讨论】:

    【解决方案2】:

    我认为你需要这个

      $('#prefetch .typeahead.name_input').typeahead(null, {
        generateOnLoad:false,
        name: 'agency_names',
        source: agency_names
      });
    

    generateOnLoad {boolean}

    空(默认)

    如果启用,将在页面加载时生成源数据(执行 Ajax 请求并准备要搜索的数据),而不是等待输入获得焦点。

    PN:此选项不适用于 dynamic: true 除非调整了其他配置。

    此外,如果您发现 rails 清单文件将您的调用添加到每个页面,只需在绑定提前类型之前检查元素是否存在:

    if($('#prefetch .typeahead.name_input').length){
          $('#prefetch .typeahead.name_input').typeahead(null, {
            generateOnLoad:false,
            name: 'agency_names',
            source: agency_names
          });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-17
      • 1970-01-01
      • 2022-06-17
      • 1970-01-01
      • 2012-05-02
      • 2012-08-01
      • 1970-01-01
      • 2018-02-22
      相关资源
      最近更新 更多