【问题标题】:How to filter the same set of data in a view via AJAX如何通过 AJAX 过滤视图中的同一组数据
【发布时间】:2017-10-13 22:11:38
【问题描述】:

我有一个message 模型,每条消息都具有我想过滤的statuscontext(type) 属性。 index 视图当前按预期显示所有消息。我的问题是,通过 AJAX 过滤这些结果的最佳方法是什么(如果可能,请举例说明)?

我想做 AJAX 的原因是我可以单击指向不同状态/上下文类型的链接,它可以替换当前显示所有 messages 的表(通过视图中的 @message.each 调用)必须有 10 个不同的动作和 10 个不同的部分,只是因为它看起来不像是 rails 方式。

设置如下:

# Message Model ## I have included the attributes and all possible values for the sake of completion ## 
message.status = ['New', 'Responded', 'Follow-up Required', 'Resolved']
message.context = ['Account Activation', 'Billing', 'Client Services', 'General Inquiry', 'Technical Support']


# Message Controller #
def index
  @messages = Message.paginate(page: params[:page], per_page: 15)
  respond_to do |format|
    format.html
    format.js
  end
end

# messages/index.html.erb #
renders a partial containing a table with @messages.each iteration

我仍然对 AJAX 非常陌生,并尝试创建 9 个不同的部分并在单击链接时让它们相互替换,或者为单个索引页面设置 9 种不同的控制器方法,只需更改 @messages 变量,也玩弄了使用 AJAX 根据单击的链接更新@messages 变量的想法,但这些似乎都不像“Rails”方式来做到这一点。

任何和所有的建议都欢迎和超级奖励点给任何人都可以 AJAXify 分页的解决方案,但我有点假设如果我可以使用 AJAX 正确显示表格,那么不应该通过 AJAX 分页太难了。

提前致谢。

【问题讨论】:

  • 我有点信息过载了。是否可以简化问题?您有一个端点,它接收一些变量信息并根据变量输入返回结果。你能描述一下那部分吗?你想解决什么问题?
  • 抱歉,我经常看到人们要求更多信息的问题,所以我尽量避免这种情况。本质上,我有一个 index view 显示所有 messages,我想通过 AJAX 选择属性来过滤消息,这样用户就不必离开页面。总消息会随着时间的推移而增长,因此需要分页。我不知道在不为每个过滤器重复代码的情况下实现这一目标的最佳方法,所以我的问题是我将如何做到这一点?谢谢
  • 所以在页面加载时所有消息都存在?
  • 正确,初始加载包含所有消息,同时不离开该页面(如果可能)我想根据属性进行过滤(据我所知,这需要类似于 Message.where(status: "xx") 的内容调用控制器)
  • 好吧,如果您的初始页面加载包含所有消息,那么您已经承受了性能损失以返回所有这些数据。我认为鉴于这种情况,简单地显示/隐藏基于过滤器的结果会更好,而不是进一步调用 ajax 来返回你已经拥有的数据。

标签: jquery ruby-on-rails ajax pagination ruby-on-rails-5


【解决方案1】:

所以经过一番头脑风暴后,我决定在index 操作中使用case 语句来更新@messages 数组,这两个参数通过具有过滤选项的链接传递,params[:status] 和@987654325 @。我将表格和过滤器链接拉成两个单独的部分,并在每次单击任何过滤器链接时(通过index.js.erb)渲染它们。

index - MessagesController

def index

  status = params[:status]
  context = params[:context]

  case status
    when "New"
      @msg_status = "New"
    when "Responded"
      @msg_status = "Responded"
    when "Follow_up", "Follow-up Required"
      @msg_status = "Follow-up Required"
    when "Resolved"
      @msg_status = "Resolved"
  end

  case context
    when "Account_Activation"
      @msg_context = "Account Activation"
    when "Billing"
      @msg_context = "Billing"
    when "Client_Services"
      @msg_context = "Client Services"
    when "General_Inquiry"
      @msg_context = "General Inquiry"
    when "Technical_Support"
      @msg_context = "Technical Support"
  end

  if @msg_status && @msg_context
    msg = Message.where(status: "#{@msg_status}")
    @messages = msg.where(context: "#{@msg_context}").paginate(page: params[:page], per_page: 15)
  elsif @msg_status
    @messages = Message.where(status: "#{@msg_status}").paginate(page: params[:page], per_page: 15)
  elsif @msg_context
    @messages = Message.where(context: "#{@msg_context}").paginate(page: params[:page], per_page: 15)
  else
    @messages = Message.paginate(page: params[:page], per_page: 15)
  end

  respond_to do |format|
    format.html
    format.js
  end
end

_message_table.html.erb - 部分显示消息

<% @messages.each do |msg| %>
  ..
<% end %>

链接传递示例params[:status]

<%= link_to(url_for(messages_path(status: 'New')), remote: true) do %>
  <i class="fa fa-envelope-o"></i> New <span class="label label-success pull-right"><%= Message.where(status: "New").count %></span>
<% end %>

链接传递示例 params[:context] - 内部链接是部分的,因此每次点击状态链接时都会刷新它们

<%= link_to(url_for(messages_path(status: "#{@msg_status}", context: 'Technical_Support')), remote: true) do %>
  <i class="fa fa-circle text-warning"></i> Technical Support
<% end %>

两个部分的渲染都由index.js.erb 处理。

这是我能想到的最“轨道”方式,同时尽可能保持 DRY 和 RESTful。以上内容非常适合我试图实现的目标,但如果有人有任何想法让它更简单/更清洁/更多“轨道”,那么我总是愿意接受建议。谢谢。

【讨论】:

    猜你喜欢
    • 2012-04-18
    • 2014-09-04
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    • 2019-03-06
    • 1970-01-01
    相关资源
    最近更新 更多