Rails / AJAX: частично не отображается? - PullRequest
0 голосов
/ 17 декабря 2018

Фон (изменено после переписки с @TomLord):

Я создаю простой сайт, содержащий только индексную страницу и без подстраниц.Страница индекса имеет поле поиска, которое принимает данные (id) и отправляет запрос GET в API RESTful, работающий в фоновом режиме.Ответ от 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

My 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)

1 Ответ

0 голосов
/ 21 декабря 2018

На "нормальном" сайте рельсов форма поиска работает следующим образом -

Вы определяете форму в представлении.По умолчанию это 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 как есть и просто добавить небольшой код для визуализации результатов как частичного.

...