jQuery 更受欢迎是有充分理由的,我不会详细说明。在其他地方有很多。
假设你想使用 jQuery,设置非常简单:
# add the following to your Gemfile under `group :development`
gem 'jquery-rails'
# run the following
$ bundle
# then let the generator install
$ rails g jquery:install
然后更新您的 Application.rb javascript 扩展默认值:
# JavaScript files you want as :defaults (application.js is always included).
config.action_view.javascript_expansions[:defaults] = %w( jquery rails )
并确保您的布局文件(例如 application.html.erb)包含这些文件:
<%= javascript_include_tag :defaults %>
对于你的模态,有很多关于如何做的意见。就我个人而言,我更喜欢根据应用程序的需要滚动我自己的模态窗口。只需要几行带有 jQuery 的 JS 就可以构建与 Rails.js 一起工作的模态:
# in a view, perhaps a _modal.html.erb partial that is included into
# your layout (probably at the bottom).
<div id="modal-container"></div>
<div id="modal">
<a href="#" class="close">close</a>
</div>
以下是我使用的模式的一些样式(scss 样式):
#modal-container {
display: none;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0,0,0,0.4);
}
#modal {
display: none;
position: absolute;
width: 600px;
left: 50%;
margin-left: (-600px - 40px) / 2;
padding: 20px;
background: #fff;
border: 5px solid #eee;
& > .close {
position: absolute;
right: 5px;
top: 5px;
color: #666;
&:hover, &:active {
color: #000;
}
}
}
这样可以避免样式/视图。您可能希望自定义这些样式以更好地适应您的应用程序,但它们非常通用,因此应该可以开始使用。
要将其集成到 Rails 中,有 2 个部分。首先,您需要让浏览器发送 AJAX 内容请求并在返回时显示模式。其次,您需要 Rails 以适当的响应进行响应。
发送 AJAX 和处理响应需要在要远程发送的链接/表单上使用 :remote => true。
<%= link_to 'New Post', new_post_path, :remote => true %>
这将在 Rails.js 将拾取的链接上创建一个数据属性,允许它自动远程提交。它期望一个 javascript 返回,并在得到它时执行该响应。您可以在每个动作respond_to 块中添加一个快速format.js,并创建一个随附的new.js.erb 文件,其中包含实际填写和显示模式所需的JS。没关系,但我们可以通过返回没有布局的模板并将模态显示/隐藏职责移动到 application.js 中来干掉它:
# in your app controller, you'll want to set the layout to nil for XHR (ajax) requests
class ApplicationController < ActionController::Base
layout Proc.new { |controller| controller.request.xhr? ? nil : 'application' }
end
使整个事情起作用的javascript:
# in application.js
$(function(){
var $modal = $('#modal'),
$modal_close = $modal.find('.close'),
$modal_container = $('#modal-container');
# This bit can be confusing. Since Rails.js sends an accept header asking for
# javascript, but we want it to return HTML, we need to override this instead.
$('a[data-remote]').live('ajax:beforeSend', function(e, xhr, settings){
xhr.setRequestHeader('accept', '*/*;q=0.5, text/html, ' + settings.accepts.html);
});
# Handle modal links with the data-remote attribute
$('a[data-remote]').live('ajax:success', function(xhr, data, status){
$modal
.html(data)
.prepend($modal_close)
.css('top', $(window).scrollTop() + 40)
.show();
$modal_container.show();
});
# Hide close button click
$('.close', '#modal').live('click', function(){
$modal_container.hide();
$modal.hide();
return false;
});
});
我有一些逻辑可以将模态窗口定位在距浏览器当前滚动位置 40px 的位置。
有了所有这些部分,当您单击带有远程属性集的链接/表单时,Rails.js 将处理提交请求,您的应用程序将知道仅返回操作的模板而没有布局,非常适合在模态窗口中显示它,然后我们上面的 javascript 将挂钩到来自 Rails.js 的 ajax:success 回调,并使用从我们的应用程序返回的模板 HTML 显示模态。
给猫剥皮的方法不止一种,构建这个功能的方法也有十几种。这绝对是 Rails 团队尚未制定更强有力的约定的领域。这只是我的处理方式,我觉得它相当干燥,需要最少的努力,并且相当灵活且面向未来。也许有人可以在此基础上构建的领域之一是使用覆盖更多基础且功能更丰富的模态/灯箱框架。如果有人这样做,我很乐意看到一篇文章!