为什么在 rails 中调用远程部分时模态不起作用?

Why does modal not works when calling a remote partial in rails?

基本设置有效:

translations/_edit_single_translation.html.erb

<div id="modalContent" class="modal-content">
  <div class="modal-header">
    <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
      <span aria-hidden="true">&times;</span>
    </button>
  </div>
  <div class="modal-body"></div>
  <div class="modal-footer">
    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
    <button type="button" class="btn btn-primary">Save changes</button>
  </div>
</div>

layouts/application.html.erb 包含:

<%= render 'translations/edit_single_translation' %>

<div id="modal-window" class="modal hide fade modal-backdrop" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div id="modalDialog" class="modal-dialog" role="document">
    Content comes here
  </div>
</div>

link:

link_to "Translate Link", translations_edit_path(:locale => locale,: key => key), local: true)

所以这行得通

来自应用程序。html.erb 我删除:

<%= render 'translations/edit_single_translation' %>

并将link更改为:

link_to "Translate Link", translations_edit_path(:locale => locale,: key => key), remote: true)

在 javascript/packs/modal-action.js 中我输入:

$("#modal-window").find(".modal-content").html("<%= j (render partial: 'translations/edit_single_translation') %>");
$("#modal-window").modal('show');

现在不行了。

添加时:

alert(\'<%= j (render partial: "translations/edit_single_translation") %>')

到模态动作。我收到 <%= j (render partial: "translations/edit_single_translation") %>

的警报

我错过了什么?

[编辑]

我发现调用了'show'方法。谷歌搜索了一两天,我发现不是:

respond_to do |format|
    format.js
    format.html
end

我不得不放:

respond_to do |format|
    format.js { render :layout => false }
    format.html
end

在'show'翻译方法中。

然后我不得不搬家

$("#modalDialog").html('<%= j (render partial: 'edit', locals: { items: @translation } ) %>');
$('#modal-window').modal();

javascript/packs/modal-action.jstranslations\show.js.erb

为了添加和更新工作,我将所有翻译放在一个范围内,键为 id。 在添加或编辑后更新相应的翻译并关闭我输入的模式:

$('#<%= params[:key].gsub(".","_") %>').html('<%= params[:value] %>');
$('#modal-window').modal('hide');

translations\create.js.erb

$('#<%= params[:i18n_backend_active_record_translation][:key].gsub(".","_") %>').html('<%= params[:i18n_backend_active_record_translation][:value] %>');
$('#modal-window').modal('hide');

translations\update.js.erb 我的添加表单是 form_with 编辑是 form_for

我的 translations_controler.erb 包含:

class TranslationsController < ApplicationController
  def index
  end

  def show
    @translation = Translation.find_by(:locale => find_locale,
                                        :key => params[:key])
    @key = params[:key]
    if @translation.nil?
      @Translation = Translation.new
    end
    respond_to do |format|
      format.js { render :layout => false }
      format.html
    end
  end

  def new
  end

  def create
    @translation = Translation.create(translation_create_params)
    respond_to do |format|
      if @translation.save
        I18n.backend.reload!
        format.json { head :no_content }
        format.js
      else
        format.json { render json: @customer.errors.full_messages, 
                            status: :unprocessable_entity }
      end
    end
  end

  def edit
  end

  def update
    respond_to do |format|
      @translation = Translation.find(t_id)
      if @translation.update(translation_update_params)
        I18n.backend.reload!
        format.json { head :no_content }
        format.js { } 
      else
        format.json { render json: @translation.errors.full_messages,
                                   status: :unprocessable_entity }
      end
    end
  end

  private
    def t_id
      params[:i18n_backend_active_record_translation][:id]
    end

    def find_locale
      params[:locale].nil? ? I18n.default_locale : params[:locale]
    end

    def translation_update_params
      params.require(:i18n_backend_active_record_translation).permit(:locale,
      :key, :value)
    end

    def translation_create_params
      params.permit(:locale, :key, :value)
    end
end

现在模态正在工作 :) :)。

这里有很多混乱。

资产管道

Javascript 放置在资产管道 (Webpacker) 中,在生产部署时编译。在 Rails 6 中,您将 "packs" - 这是 app/javascripts/packs 中的资产清单。这意味着您 link 从您的布局中获取的主文件,它需要您正在使用的库以及您的代码。我们鼓励您将自己的应用程序代码放在 app/javascripts.

Webpacker 不会通过 ERB 解释器传递 .js 文件,因此期望 $("#modal-window").find(".modal-content").html("<%= j (render partial: 'translations/edit_single_translation') %>") 会输出字符串 "<%= j (render partial: 'translations/edit_single_translation') %>" 以外的任何内容是完全不现实的。

与带有 webpacker 的 sprockets 不同,您实际上必须 manually install .js.erb integration。但是请记住,该文件仍然是在部署时编译的,而不是在运行时编译的,因此上下文将是完全错误的,您将无法访问可以让您呈现部分内容的助手和视图上下文。

Rails UJS 和 js.erb

当您在 link 上使用 data-remote 和表单 Rails 时,UJS 将发送 ajax 请求 application/javascript 内容类型。然后,您的控制器应该响应 js 并呈现 js.erb 视图,然后通过在包含响应的页面上创建脚本元素来评估该视图,以便视图更改现有页面。

class ThingsController < ApplicationController
  def show
    @thing = Thing.find(params[:id])
    respond_to do |f|
      format.js 
      format.html
    end
  end
end
// app/views/things/show.js.erb
el = document.getElementById("#thing");
el.innerHTML = "<%= j @thing.name %>";


亚格尼

如果你只是想在模态中渲染一个部分,你真的不需要首先将模板输出到 JS 中。您可以只使用 content_for 在您的布局中创建一个您的视图可以填充的占位符:

<div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenter" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">
          <%= content_for :modal_title %>Modal Title<% end %>
        </h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <%= content_for :modal %><% end %>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>

稍后在视图中您可以填写内容:

<% content_for :modal_title, "Edit translation", flush: true %>
<% content_for :modal do %>
  <%= render partial: 'translations/edit_single_translation' %>
<% end %>

现在您 JavaScript 所要做的就是显示模态框。