在 Rails3 中,處理 JavaScript 改採用 UJS 的方式,也就是以往 inline JS 的情況將不復見,link_to_remote 跟 remote_form_for 都沒有了:
例如:
link_to 'Logout', session_path, :method => :delete
產生出來的是:
<a href="/session" data-method="delete" rel="nofollow">Logoout</a>
例如
link_to 'Ajax delete', person_path(person), :remote => true, :confirm => "Are you sure?"
產生出來的是
<a href="/people/1" data-confirm="Are you sure?" data-method="delete" data-remote="true" rel="nofollow">Ajax delete</a> # 點下去會向 Server 要求 JavaScript 內容執行
Rails3 預設還是使用 Prototype.js,要換成 jQuery 非常簡單。首先在產生 rails 專案時,可以輸入 rails your_project -J 就不會產生 Prototype.js 的檔案。
修改 /public/javascripts/rails.js 這個檔案,內容換成 github.com/rails/jquery-ujs/blob/master/src/rails.js 這個官方提供的 jQuery js driver。
在 Rails layout 的 HTML head 中加入:
<%= csrf_meta_tag %> <%= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js" %> <%= javascript_include_tag 'rails' %>
其中 csrf_mate_tag 產生的是做 CSRF 防禦的 authenticity_token,以往這也是 inline 在 HTML 中,現在則是先宣告在 HTML head 中。
另外要提醒你,如果你有使用 RJS 的話,Rails3 的 RJS 還是只會產生 prototype.js 的版本。所以如果非得用 RJS 的話,目前恐怕還是得裝以往 Rails2 用的 jRails,這好像有點蠢。也許是時候把 RJS 徹底揚棄,直接寫 jQuery 好了(?)
例如上面的 Ajax delete 例子,它的 controller 跟 js 可以這樣:
# people_controller.rb def destroy @person = Person.find(params[:id]) @person.destroy respond_to do |format| format.html { redirect_to(people_url) } format.js # destroy.js.erb end end # destroy.js.erb jQuery("#<%= dom_id(@person)%>").remove();
rjs一直口碑不好,是时候和它说byebye了
rjs确实应该废弃,它不光返回数据,还返回逻辑,违背了Ajax本性。
prototype.js失效可能是因为对自定义属性的取值问题,很多浏览器为了速度都会忽略掉自定义属性,这个地方要做很多hack。
这样的修改总感觉很是别扭,如果要处理Ajax的请求,似乎每个action都要对应着一个xx.js.erb文件,相对来说感觉不如以前的灵活啊
clone 完 github.com/rails/jquery-ujs.git
裡面的 README.md 說到可以用 gem install 從 prototype 轉 jQuery for rails
# Gemfile
gem ‘jquery-rails’, ‘>= 0.2.6’
再
bundle install
rails generate jquery:install