本文介绍了Rails,render_async gem:如何在通过 ajax 加载的部分中使用 render_async的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
问题
我正在使用 gemrender_async"异步渲染内容.
当我访问像 localhost:3000/people
这样的页面时,内容会按预期异步呈现.
但是,如果内容位于通过 ajax 加载的部分中,则不会异步呈现内容.我不明白为什么它不起作用,我不知道如何修复它.
如何使用 render_async,如果它在通过 ajax 加载的部分中?
gem render_async:https://github.com/renderedtext/render_async
什么有效
当我调用像 localhost:3000/people
这样的索引页面时,render_async 按预期工作.
这是有效的代码:
people/index.html.erb
人物
...<div class="人"><%= 渲染部分: "people/show", collection: people, as:person %>
在 people-div 中,部分 _show.html.erb 正在加载.
people/_show.html.erb
人员
...<%= render_async render_shared_path(parent_type: "Person", parent_id: person.id), 'data-turbolinks-track': 'reload', error_message: '<p>对不起,用户加载出错:(</p>'做%>共享 lädt!<%结束%>
此代码按预期工作.render_async
加载名为 _children.html.erb 的部分.当用户访问 people/index.html.erb 时,所有 _children-partials 都被异步加载.
什么不起作用
在 people/index.html 上,当用户按下按钮时,people
-div 将通过 ajax 重新加载.以下是重新加载人员 div 的方式:
var people_div = ".people";$( people_div ).fadeOut( "fast", function() {content = $("<%= escape_javascript( render 'people/people', people: @people ) %>")$(people_div).replaceWith(function(){返回 $(content).hide().fadeIn("fast");});});
正在重新加载的代码与 people/index.js 中的代码相同.只有参数发生了变化.
在 people-div 重新加载后,不会异步渲染任何内容._children-partials 未加载.rails 控制台或 Web 控制台中没有消息.
唯一可见的是占位符:Shared lädt!".
可能是什么问题?
代码
_show.html.erb
<%= render_async render_shared_path(parent_type: "Person", parent_id: person.id), 'data-turbolinks-track': 'reload', error_message: '<p>对不起,用户加载去了错误:(</p>'做%>共享 lädt!<%结束%>
routes.rb
#renderget '/render_shared', to: 'render#render_shared', as: 'render_shared'
render_controller.rb
def render_sharedparent_type = params[:parent_type]parent_id = params[:parent_id]@parent = parent_type.singularize.classify.constantize.find(parent_id)呈现部分:共享/孩子"结尾
_children.html.erb
<div class="shared-<%=parent.class.name.downcase%>-<%=parent.id%>"><p><a class="btn btn-link btn-sm" data-toggle="collapse" href=".address-<%= parent.id %>-<%= parent.class.to_s.downcase %>"role="button" aria-expanded="false" aria-controls="collapseExample"><%= fa_icon "地址卡" %>访问地址</a></p><div class="折叠 mb-2 地址-<%= parent.id %>-<%= parent.class.to_s.downcase %>"><%= render "addresses/show", address: parent.address %>
application.html.erb
<title>MyApp</title><%= csrf_meta_tags %><%= csp_meta_tag %><%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %><%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %><%= content_for :render_async %>头部>
解决方案
在深入研究这个问题后,问题似乎出在 render_async 的 Vanilla JS 部分.Vanilla JS 不评估来自父 render_async 响应的脚本标签.
作为快速修复,我建议您尝试使用 render_async 的 jQuery 部分,因为它确实会评估脚本标签.您可以通过执行以下操作来打开 jQuery:
RenderAsync.configure 做 |config|config.jquery = true # 这将渲染 jQuery 代码,并跳过 Vanilla JS 代码结尾
说明
当您尝试渲染嵌套的部分时,render_async 会在脚本标记内加载 JS 代码,该标记需要进行评估才能执行另一个请求.jQuery 有一个强大的方法 .replaceWith(text)
,它评估文本变量中的任何脚本标签.这在普通 JS 中并不容易实现.我正在为此想出一个解决方案.
如果有人知道如何实现这一点,您可以在此 GitHub 问题上做出贡献 https://github.com/renderedtext/render_async/issues/30
Problem
I'm using the gem "render_async" to render content asynchronously.
When I visit a page like localhost:3000/people
, the content gets rendered asynchronously, as expected.
However, the content does not get rendered asynchronously, if it is inside a partial that got loaded via ajax. I don't understand why it isn't working and I don't know how to fix it.
How can I use render_async, if it is inside a partial that got loaded via ajax?
gem render_async: https://github.com/renderedtext/render_async
What works
When I call an index page like localhost:3000/people
, render_async works as expected.
Here is the code that works:
people/index.html.erb
<h1>People</h1>
...
<div class="people">
<%= render partial: "people/show", collection: people, as: :person %>
</div>
Inside the people-div, the partial _show.html.erb is being loaded.
people/_show.html.erb
<h1>Person</h1>
...
<%= render_async render_shared_path(parent_type: "Person", parent_id: person.id), 'data-turbolinks-track': 'reload', error_message: '<p>Sorry, users loading went wrong :(</p>' do %>
Shared lädt!
<% end %>
This code works as expected. The render_async
loads a partial called _children.html.erb. When a user visits people/index.html.erb, all _children-partials are being loaded asynchronously.
What doesn't work
On people/index.html, when the user presses a button, the people
-div is being reloaded via ajax. Here is how the people div is being reloaded:
var people_div = ".people";
$( people_div ).fadeOut( "fast", function() {
content = $("<%= escape_javascript( render 'people/people', people: @people ) %>")
$(people_div).replaceWith(function(){
return $(content).hide().fadeIn("fast");
});
});
The code that is being reloaded is the same as in people/index. Only the params change.
After the people-div is reloaded, no content gets rendered asynchronously. The _children-partials are not being loaded.There are no messages in the rails console or in web console.
The only thing that is visible is the placeholder: "Shared lädt!".
What might be the problem?
Code
_show.html.erb
<%= render_async render_shared_path(parent_type: "Person", parent_id: person.id), 'data-turbolinks-track': 'reload', error_message: '<p>Sorry, users loading went wrong :(</p>' do %>
Shared lädt!
<% end %>
routes.rb
#render
get '/render_shared', to: 'render#render_shared', as: 'render_shared'
render_controller.rb
def render_shared
parent_type = params[:parent_type]
parent_id = params[:parent_id]
@parent = parent_type.singularize.classify.constantize.find(parent_id)
render partial: "shared/children"
end
_children.html.erb
<% parent = parent || @parent %>
<div class="shared-<%=parent.class.name.downcase%>-<%=parent.id%>">
<p>
<a class="btn btn-link btn-sm" data-toggle="collapse" href=".address-<%= parent.id %>-<%= parent.class.to_s.downcase %>" role="button" aria-expanded="false" aria-controls="collapseExample">
<%= fa_icon "address-card" %> Adresse anzeigen
</a>
</p>
<div class="collapse mb-2 address-<%= parent.id %>-<%= parent.class.to_s.downcase %>" >
<%= render "addresses/show", address: parent.address %>
</div>
</div>
application.html.erb
<head>
<title>MyApp</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= content_for :render_async %>
</head>
解决方案
After looking more into this issue, the problem seems to be in the Vanilla JS part of render_async. Vanilla JS doesn't evaluate script tags that come from the parent render_async response.
As a quick fix, I suggest that you try to use jQuery part of render_async, since it does evaluate script tags. You can turn on jQuery by doing:
RenderAsync.configure do |config|
config.jquery = true # This will render jQuery code, and skip Vanilla JS code
end
Explanation
When you try to render a nested partial, render_async loads JS code inside a script tag that needs to be evaluated to do another request. jQuery has a powerfull method .replaceWith(text)
which evaluates any script tags in the text variable. This is not so easy to achieve in plain JS. I'm trying to come up with a solution for this.
If anyone has an idea how to achieve this, you can contribute at this GitHub issue https://github.com/renderedtext/render_async/issues/30
这篇关于Rails,render_async gem:如何在通过 ajax 加载的部分中使用 render_async的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!