如何为coffeescript搜索添加时间延迟

时间:2016-09-12 18:04:10

标签: javascript ruby-on-rails coffeescript

当用户搜索姓氏时,响应正在跳跃。

这里发生了什么。我的例子就是搜索Moon这个名字。

因为Moon是最具体的,它运行速度最快(例如15.08) http://localhost:3000/contacts/search_contacts?search_term=Moon&order_by=first_name&sort_direction=asc&grade=all&group=allhttp://localhost:3000/contacts/search_contacts

因为M是最不具体的,所以它运行最慢的搜索(例如22.47) SEARCH_TERM = M&安培; ORDER_BY = first_name的&安培; sort_direction = ASC&安培;等级=所有&安培;基团=所有 http://localhost:3000/contacts/search_contacts

Mo& Moo也跑了。

结果,搜索找到Moon但是被Moo' Mo' Mo'的搜索结果覆盖。 &安培; ' M' (并导致跳转以及搜索无法正常工作)。

这是代码(使用coffeescript)。

  class @ContactsSearch

  constructor: ->

    SearchUtils.configCheckBoxSelectAll('contacts-checkbox-select-all', 'contacts-container','contacts-delete-button')

    SearchUtils.configBtnGroup('contacts-btn-group-grade', doSearch)
    SearchUtils.configBtnGroup('contacts-btn-group-order-by', doSearch)
    SearchUtils.configBtnGroup('contact-btn-group', doSearch)
    SearchUtils.configSortDirBtn('contacts-sort-order-toggle', doSearch)

    configDeleteButton()
    configAjaxPaginationLinks()

    search_box = $('#contacts-search-input')
    search_box.data('search-url')
    search_box.bind 'input', (e, data) ->
      doSearch()


  doSearch = ->
    search_box = $('#contacts-search-input')

    btn_group_grade = $('#contacts-btn-group-grade')
    btn_group_order_by = $('#contacts-btn-group-order-by')
    sort_order_toggle = $('#contacts-sort-order-toggle')
    contact_btn_group = $('#contact-btn-group')

    SearchUtils.resetMasterCheckbox('contacts-checkbox-select-all', 'contacts-delete-button')

    ajaxCall(search_box.data('search-url') + "?search_term=" + search_box.val() + "&order_by=" + btn_group_order_by.data('value') + "&sort_direction=" + sort_order_toggle.data('value') + "&grade=" + btn_group_grade.data('value') + "&group=" + contact_btn_group.data('value'))

  ajaxCall = (finalUrl) ->
    search_box = $('#contacts-search-input')
    contacts_table = $('#contacts-container')
    $.ajax
      url: finalUrl
      type: "GET"
      error: (data, status, xhr) ->
        # do nothing
      success: (data, status, xhr) =>
        contacts_table.html(data)
        configAjaxPaginationLinks()
        $('[data-toggle="popover"]').popover()

        SearchUtils.configContainerCheckBoxs('contacts-checkbox-select-all', 'contacts-container','contacts-delete-button')


  configDeleteButton = ->
    $("#contacts-delete-button").click (event) ->
      event.preventDefault()
      bootbox.confirm "Are you sure?", (result) ->
        if result
          deleteSelectedContacts()

  configAjaxPaginationLinks = ->
    $('#contacts-container').find(".pagination a").click (event) ->
      event.preventDefault()
      search_box = $('#contacts-search-input')
      finalUrl = search_box.data('search-url') + "?" + $(this).attr("href").split("?").slice(1)
      ajaxCall(finalUrl)

  deleteSelectedContacts = ->
    url = $("#contacts-delete-button").data('url')

    deleteIDs = $(".contact-search-item:checked").map(->
      $(this).val()
    ).get()

    $.ajax
      url: url
      type: "POST"
      data: JSON.stringify({ ids: deleteIDs }),
      contentType: "application/json; charset=utf-8",
      dataType: "json"
      error: (data, status, xhr) ->
        # do nothing
      success: (data, status, xhr) =>
        doSearch()

document.addEventListener "turbolinks:load", ->
  new ContactsSearch()

我是coffeescript的新手,但我认为我需要改变逻辑。具体来说,我认为我需要为此添加时间延迟:

 search_box.bind 'input', (e, data) ->
      doSearch()

我尝试过更改'输入'到#key;'只要手指从键盘上掉下来就可以进行搜索,但这样做不起作用。不确定语法是否错误或者不是coffeescript约定。

或者,我认为我需要在cofeescript上添加某种时间延迟但不确定语法?

任何想法?
非常感谢。

1 个答案:

答案 0 :(得分:1)

您的评论是正确的,因为您需要去除您的输入。您只想在用户暂时停止输入时开始搜索。

执行此操作的最佳方式是setTimout

setTimeout将在X毫秒内调用方法。它还返回一个id,您可以通过该ID取消超时。您需要使用以下两个功能:

# We want to wait for the user to stop typing for 1 second
SEARCH_DELAY = 1000

# here we will save the timeout id so we can cancel the search early
#   if the user keeps on typing
searchTimeoutId = null


search_box.bind 'input', ->
  # First clear the old search timeout if it exists
  clearTimeout searchTimeoutId
  # Then set a new timeout to search the text box contents if the user
  #   doesn't continue typing within 1 second
  searchTimeoutId = setTimeout doSearch, SEARCH_DELAY

请询问您是否需要进一步解释。

旁注:

这在本地开发时可以正常工作,但有一些现实世界的场景无法覆盖。

假设用户正在输入moon landingmoonlanding之间暂停1秒。这意味着将向服务器发送两个单独的搜索。在当地这很好,他们应该以正确的顺序回来。但由于介于两者之间的复杂网络,订单无法保证。

我建议您发送时间戳以及每个查询。然后你可以检查你是否已收到&呈现了一个更新的请求,并丢弃旧的响应,这些响应在没有渲染的情况下太慢。