Problema

Estoy usando la gema "render_async" para representar contenido de forma asincrónica.

Cuando visito una página como localhost:3000/people, el contenido se procesa de forma asincrónica, como se esperaba.

Sin embargo, el contenido no se procesa de forma asincrónica, si está dentro de un parcial que se cargó a través de ajax. No entiendo por qué no funciona y no sé cómo solucionarlo.

¿Cómo puedo usar render_async, si está dentro de un parcial que se cargó a través de ajax?

Gem render_async: https://github.com/renderedtext/render_async

Que funciona

Cuando llamo a una página de índice como localhost:3000/people, render_async funciona como se esperaba.

Aquí está el código que funciona:

People / index.html.erb

<h1>People</h1>
...
    <div class="people">
        <%= render partial: "people/show", collection: people, as: :person %>
    </div>

Dentro de people-div, se está cargando el _show.html.erb parcial.

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 %>

Este código funciona como se esperaba. El render_async carga un parcial llamado _children.html.erb. Cuando un usuario visita people / index.html.erb, todos los _children-parciales se cargan de forma asincrónica.

Lo que no funciona

En people / index.html, cuando el usuario presiona un botón, el people - div se recarga a través de ajax. Así es como se recarga el div de personas:

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");
    });

});

El código que se está recargando es el mismo que en people / index. Solo cambian los parámetros.

Una vez que se vuelve a cargar people-div, no se procesa ningún contenido de forma asincrónica. Los _children-parciales no se están cargando. No hay mensajes en la consola rails o en la consola web.

Lo único que es visible es el marcador de posición: "Shared lädt!".

¿Cuál podría ser el problema?

Código

_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>
1
Metaphysiker 16 oct. 2018 a las 08:04

2 respuestas

La mejor respuesta

Después de investigar más este tema, el problema parece estar en la parte Vanilla JS de render_async. Vanilla JS no evalúa las etiquetas de script que provienen de la respuesta principal render_async.

Como solución rápida , le sugiero que intente utilizar jQuery como parte de render_async, ya que evalúa las etiquetas de script. Puede activar jQuery haciendo:

RenderAsync.configure do |config|
  config.jquery = true # This will render jQuery code, and skip Vanilla JS code
end

Explicación

Cuando intentas renderizar un parcial anidado, render_async carga código JS dentro de una etiqueta de secuencia de comandos que debe evaluarse para realizar otra solicitud. jQuery tiene un método poderoso .replaceWith(text) que evalúa cualquier etiqueta de script en la variable de texto. Esto no es tan fácil de lograr en JS simple. Estoy tratando de encontrar una solución para esto.

Si alguien tiene una idea de cómo lograr esto, puede contribuir en este número de GitHub https: // github .com / renderingtext / render_async / issues / 30

3
okliv 12 sep. 2019 a las 21:34

Creo que el problema aquí es que el código JavaScript render_async no se activa porque depende de DOMContentLoaded o $ (document) .ready () para activarse.

En su caso, esos eventos se activan antes que el código JavaScript anidado de render_async se cargue en la página.

Tengo planes para mejorar esta lógica. Crearía la posibilidad de realizar la lógica render_async inmediatamente, si el documento está listo, o escuchar el documento para estar listo y luego realizar la lógica (como la implementación actual).

Además, se ha planteado un problema similar en los problemas https://github.com/renderedtext/render_async / issues / 70

2
Nikola Đuza 16 oct. 2018 a las 17:28