为什么在 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">×</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.js
到 translations\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">×</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 所要做的就是显示模态框。
基本设置有效:
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">×</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.js
到 translations\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">×</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 所要做的就是显示模态框。