首页 > 解决方案 > Rails/AJAX:部分不显示?

问题描述

背景(与@TomLord 对应后更改):

我正在构建一个只有索引页面而没有子页面的简单站点。索引页面有一个“搜索”字段,它接受输入 ( id) 并向后台运行的 RESTful API 发送 GET 请求。API 的响应是 JSON {"market price": "4306057.0", "retail price": "4995000.0"}

我想将此结果与搜索字段一起显示在索引页面上。但是,当我按下按钮时,结果不会显示在任何地方


代码

index.html.erb

<section id="search">
  <div class="container">
    <%= form_tag({controller: "model_request", action: "result"}, method: "get", remote: true) do %>
      <%= label_tag(:q, "Search for") %>
      <%= text_field_tag(:q, "913384637") %>
      <%= submit_tag("Get the price!") %>
    <% end %>
  </div>
</section>

<section id="display_result">
  <div class="container">
  </div>
</section>

modelrequest_controller.rb看起来像这样:

class ModelrequestController < ApplicationController

  def result
    id = params['q'].capitalize
    response = RestClient::Request.execute(
      method:  :get,
      url:     "http://0.0.0.0:80/?id=#{id}")
    @result = JSON.parse response

    respond_to do |format|
      format.js {render layout: false}
    end
  end

  end

我的routes.rb

Rails.application.routes.draw do

  root 'index#index'

  match "/modelrequest", to: "modelrequest#result", via: 'get'

end

结果的 javascript 如下所示:

result.js.erb

$("#display_result").html("<%= escape_javascript(render partial: 'modelrequest/result', locals: { result: @result } ) %>");

_result.html.erb显示部分的简单方法是

<div id="display_result">
  <%= @result %>
</div>

输出

Started GET "/model_request?utf8=%E2%9C%93&q=913384637&commit=Get%20the%20price!" for 127.0.0.1 at 2018-12-19 20:55:33 +0100
Processing by ModelRequestController#result as JS
  Parameters: {"utf8"=>"✓", "q"=>"913384637", "commit"=>"Get the price!"}
  Rendering model_request/result.js.erb
  Rendered model_request/_result.html.erb (0.8ms)
  Rendered model_request/result.js.erb (6.8ms)
Completed 200 OK in 383ms (Views: 11.6ms | ActiveRecord: 0.0ms)

标签: ruby-on-railsrubyhaml

解决方案


在“正常”的 Rails 站点中,搜索表单的工作方式如下 -

您在视图中定义一个表单。默认情况下,这会将POST数据发送到端点 - 但您也可以通过GET请求来执行此操作。在您的情况下,您最初选择:

form_tag("/search", method: "get")

这会将表单数据GET /search同步发送到 ,因此会执行完整的页面重新加载。

这是一件非常有效的事情。但是,您希望保留在索引页面上- 因此请求需要是异步的:

form_tag("/search", method: "get", remote: true)

...但是现在,该端点需要做一些不同的事情。它需要部分更新当前页面,而不是渲染新页面

在 Rails 应用程序中,标准方法是按照以下方式进行操作:

# In the controller action, e.g. SearchController
def show
  @results = # ...

  respond_to do |format|
    format.js {render layout: false}
  end
end

# In the view, e.g. `search/show.js.erb`
$("#display_result").html("<%= escape_javascript(render partial: 'results', locals: { results: @results } ) %>");

# In an HTML partial, e.g. `search/_results.html.erb`
<% results.each do %>
  ...

关键思想是在您的主页 ( index.html.erb?) 上,您必须有一个容器来显示结果。然后,您只是在该容器内呈现 HTML 更新,而不是呈现新页面。


当然,这不是唯一的方法。现代网站通常会为搜索结果获取 JSON 数据,然后确定如何通过 JavaScript 显示该数据。

但是,上述方法是当前设计中最“最小”的更改 - 无需添加额外的设计模式,您可以保留大部分现有haml/erb模板,只需添加一些代码即可将结果呈现为部分的。


推荐阅读