简体   繁体   English

在 Rails 中明确响应格式和页面重新加载 html 响应

[英]Clarity on response formats and page reload for html response in Rails

I would like to understand the response format actions in Rails.我想了解 Rails 中的响应format操作。 Suppose I have a link_to in my partial which is rendered in show page like below:假设我的部分中有一个link_to ,它在show页面中呈现如下:

show.html.erb显示.html.erb

<%= render partial: 'my_partial', locals: { stage: @stage } %>

my_partial.html.erb my_partial.html.erb

<% case 'stage' %>
<% when 'beginning' %>
  <%= link_to 'Submit', { controller: 'my_controller', action: 'update_model' } %>
<% when 'ongoing' %>
  <%= render partial: 'another_partial' %>
<% end %>

my_controller.rb my_controller.rb

def update_model
  #do something
  respond_to do |format|
    format.json { render json: { some_key: some_value } }
    format.js { render partial: 'path_to_partial/partial.js' }
    format.html { redirect_to action: 'show' }
  end
end

Here whenever show page is loaded for the first time @stage will be beginning and then on clicking link_to 'Submit' then before the response from controller the @stage will be changed to ongoing .在这里,每当第一次加载show页面时, @stagebeginning ,然后单击link_to 'Submit'然后在来自控制器的响应之前@stage将更改为ongoing

Now Whenever I click on link_to , the page reloads and the response is in html so format.html is sent.现在每当我点击link_to ,页面都会重新加载并且responsehtml因此format.html被发送。 If I add remote: true then the response is in js and the page does not reload because it is remote .如果我添加remote: true则响应在js并且页面不会重新加载,因为它是remote

So the exact functionality that I want is to re render the show page and then inside the my_partial it should go to when ongoing and then render the another_partial page without reloading.所以我想要的确切功能是重新呈现show页面,然后在my_partial内部它应该when ongoing转到,然后在不重新加载的情况下呈现another_partial页面。 This happens in the same url.这发生在同一个网址中。

What I am trying to understand is why does the page reload when it is the same url?我想了解的是为什么页面在相同的 url 时会重新加载? Is that how format.html works? format.html就是这样工作的吗? What should I do to render the show page again but without reloading the page?我应该怎么做才能再次呈现show页面但不重新加载页面?

What the respond_to do |format| respond_to do |format| does it looks which response the incoming http request is expecting.它是否查看传入的 http 请求期望的响应。 Normally, if you click on a link or submit a form, it expects html.通常,如果您单击链接或提交表单,它需要 html。 But, as you state correctly, if you add remote: true the http request issued by the link is expecting javascript.但是,正如您所说的那样,如果您添加remote: true ,则链接发出的 http 请求需要 javascript。 Now you want to rerender only the partial, not the whole page.现在您只想重新呈现部分页面,而不是整个页面。 You can do it like so in the controller你可以在控制器中这样做

def update_model
 ...
  respond_to do |format|
    ...
    format.js 
    ...
  end
end

Don't give a block to format.js this will automatically render a file in the views which - like always - should be named like the controller action.不要给format.js一个块,这将自动在视图中渲染一个文件 - 像往常一样 - 应该像控制器动作一样命名。 So update_model.js.erb And here you can decide what to do.所以update_model.js.erb在这里你可以决定做什么。 So for example find the div that holds your partial and then rerender it.因此,例如找到包含您的部分的 div,然后重新渲染它。 Thanks to .erb you can write embedded ruby code in this js file too.感谢.erb你也可以在这个 js 文件中编写嵌入的 ruby​​ 代码。 And this is where you decide which part to rerender or whatever to do (toggle classes,...)这是您决定要重新渲染的部分或做什么的地方(切换类,...)

const container = document.querySelector("#container-for-partial")
const partial = "<%= j render 'some_partial' %>"
// Inject HTML to partial
container.innerHTML = partial

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM