Rails3 如何換使用 jQuery

在 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();

參與討論

6 則留言

  1. 自動引用通知: Joe on Rails / rails ..
  2. rjs确实应该废弃,它不光返回数据,还返回逻辑,违背了Ajax本性。

    prototype.js失效可能是因为对自定义属性的取值问题,很多浏览器为了速度都会忽略掉自定义属性,这个地方要做很多hack。

  3. 这样的修改总感觉很是别扭,如果要处理Ajax的请求,似乎每个action都要对应着一个xx.js.erb文件,相对来说感觉不如以前的灵活啊

發佈留言

發表迴響