Rails、render_async gem:如何在通过 ajax 加载的部分中使用 render_async
Rails, render_async gem: How to use render_async inside a partial that is loaded via ajax
问题
我正在使用 gem "render_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
<h1>People</h1>
...
<div class="people">
<%= render partial: "people/show", collection: people, as: :person %>
</div>
里面的人-div,正在加载部分_show。html.erb。
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 %>
此代码按预期工作。 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(){
return $(content).hide().fadeIn("fast");
});
});
正在重新加载的代码与 people/index 中的代码相同。只有参数改变。
重新加载 people-div 后,不会异步呈现任何内容。 _children-partials 没有 loaded.There 在 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>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>
申请.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>
我认为这里的问题是 render_async JavaScript 代码没有被触发,因为它依赖于 DOMContentLoaded 或 $(document).ready() 被触发。
在您的情况下,这些事件在 嵌套的 render_async JavaScript 代码加载到页面上之前触发。
我有计划改进这个逻辑。如果文档准备就绪,我会创建一个立即执行 render_async 逻辑的可能性,或者监听文档准备就绪然后执行逻辑(就像当前的实现一样)。
此外,问题 https://github.com/renderedtext/render_async/issues/70
中也提出了类似的问题
进一步研究这个问题后,问题似乎出在 render_async 的 Vanilla JS 部分。 Vanilla JS 不会评估来自父 render_async 响应的脚本标签。
作为 快速修复,我建议您尝试使用 render_async 的 jQuery 部分,因为它会评估脚本标签。您可以通过以下方式打开 jQuery:
RenderAsync.configure do |config|
config.jquery = true # This will render jQuery code, and skip Vanilla JS code
end
说明
当您尝试呈现嵌套部分时,render_async 会在脚本标记内加载 JS 代码,需要对其进行评估以执行另一个请求。 jQuery 有一个强大的方法 .replaceWith(text)
可以评估文本变量中的任何脚本标签。这在普通 JS 中并不容易实现。我正在尝试为此提出解决方案。
如果有人知道如何实现这一点,您可以在此 GitHub 问题上做出贡献 https://github.com/renderedtext/render_async/issues/30
问题
我正在使用 gem "render_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
<h1>People</h1>
...
<div class="people">
<%= render partial: "people/show", collection: people, as: :person %>
</div>
里面的人-div,正在加载部分_show。html.erb。
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 %>
此代码按预期工作。 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(){
return $(content).hide().fadeIn("fast");
});
});
正在重新加载的代码与 people/index 中的代码相同。只有参数改变。
重新加载 people-div 后,不会异步呈现任何内容。 _children-partials 没有 loaded.There 在 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>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>
申请.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>
我认为这里的问题是 render_async JavaScript 代码没有被触发,因为它依赖于 DOMContentLoaded 或 $(document).ready() 被触发。
在您的情况下,这些事件在 嵌套的 render_async JavaScript 代码加载到页面上之前触发。
我有计划改进这个逻辑。如果文档准备就绪,我会创建一个立即执行 render_async 逻辑的可能性,或者监听文档准备就绪然后执行逻辑(就像当前的实现一样)。
此外,问题 https://github.com/renderedtext/render_async/issues/70
中也提出了类似的问题进一步研究这个问题后,问题似乎出在 render_async 的 Vanilla JS 部分。 Vanilla JS 不会评估来自父 render_async 响应的脚本标签。
作为 快速修复,我建议您尝试使用 render_async 的 jQuery 部分,因为它会评估脚本标签。您可以通过以下方式打开 jQuery:
RenderAsync.configure do |config|
config.jquery = true # This will render jQuery code, and skip Vanilla JS code
end
说明
当您尝试呈现嵌套部分时,render_async 会在脚本标记内加载 JS 代码,需要对其进行评估以执行另一个请求。 jQuery 有一个强大的方法 .replaceWith(text)
可以评估文本变量中的任何脚本标签。这在普通 JS 中并不容易实现。我正在尝试为此提出解决方案。
如果有人知道如何实现这一点,您可以在此 GitHub 问题上做出贡献 https://github.com/renderedtext/render_async/issues/30