<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 在 Rails 中使用 JavaScript 本文介紹 Rails 內建對 Ajax 和 JavaScript 等的支持,使用這些功能可以輕易的開發強大的 Ajax 程序。 讀完本文,你將學到: * Ajax 基本知識; * 非侵入式 JavaScript; * 如何使用 Rails 內建的幫助方法; * 如何在服務器端處理 Ajax; * Turbolinks 簡介; ### Chapters 1. [Ajax 簡介](#ajax-%E7%AE%80%E4%BB%8B) 2. [非侵入式 JavaScript](#%E9%9D%9E%E4%BE%B5%E5%85%A5%E5%BC%8F-javascript) 3. [內建的幫助方法](#%E5%86%85%E5%BB%BA%E7%9A%84%E5%B8%AE%E5%8A%A9%E6%96%B9%E6%B3%95) * [`form_for`](#form_for) * [`form_tag`](#form_tag) * [`link_to`](#link_to) * [`button_to`](#button_to) 4. [服務器端處理](#%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%AB%AF%E5%A4%84%E7%90%86) * [一個簡單的例子](#%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E4%BE%8B%E5%AD%90) 5. [Turbolinks](#turbolinks) * [Turbolinks 的工作原理](#turbolinks-%E7%9A%84%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86) * [頁面內容變更事件](#%E9%A1%B5%E9%9D%A2%E5%86%85%E5%AE%B9%E5%8F%98%E6%9B%B4%E4%BA%8B%E4%BB%B6) 6. [其他資源](#%E5%85%B6%E4%BB%96%E8%B5%84%E6%BA%90) ### 1 Ajax 簡介 在理解 Ajax 之前,要先知道網頁瀏覽器常規的工作原理。 在瀏覽器的地址欄中輸入 `http://localhost:3000` 后,瀏覽器(客戶端)會向服務器發起一個請求。然后瀏覽器會處理響應,獲取相關的資源文件,比如 JavaScript、樣式表、圖片,然后顯示頁面內容。點擊鏈接后發生的事情也是如此:獲取頁面內容,獲取資源文件,把全部內容放在一起,顯示最終的網頁。這個過程叫做“請求-響應循環”。 JavaScript 也可以向服務器發起請求,并處理響應。而且還能更新網頁中的內容。因此,JavaScript 程序員可以編寫只需更新部分內容的網頁,而不用從服務器獲取完整的頁面數據。這是一種強大的技術,我們稱之為 Ajax。 Rails 默認支持 CoffeeScript,后文所有的示例都用 CoffeeScript 編寫。本文介紹的技術,在普通的 JavaScript 中也可使用。 例如,下面這段 CoffeeScript 代碼使用 jQuery 發起一個 Ajax 請求: ``` $.ajax(url: "/test").done (html) -> $("#results").append html ``` 這段代碼從 `/test` 地址上獲取數據,然后把結果附加到 `div#results`。 Rails 內建了很多使用這種技術開發程序的功能,基本上無需自己動手編寫上述代碼。后文介紹 Rails 如何為開發這種程序提供幫助,不過都構建在這種簡單的技術之上。 ### 2 非侵入式 JavaScript Rails 使用一種叫做“非侵入式 JavaScript”(Unobtrusive JavaScript)的技術把 JavaScript 應用到 DOM 上。非侵入式 JavaScript 是前端開發社區推薦使用的方法,但有些教程可能會使用其他方式。 下面是編寫 JavaScript 最簡單的方式,你可能見過,這叫做“行間 JavaScript”: ``` <a href="#" onclick="this.style.backgroundColor='#990000'">Paint it red</a> ``` 點擊鏈接后,鏈接的背景會變成紅色。這種用法的問題是,如果點擊鏈接后想執行大量代碼怎么辦? ``` <a href="#" onclick="this.style.backgroundColor='#009900';this.style.color='#FFFFFF';">Paint it green</a> ``` 太別扭了,不是嗎?我們可以把處理點擊的代碼定義成一個函數,用 CoffeeScript 編寫如下: ``` paintIt = (element, backgroundColor, textColor) -> element.style.backgroundColor = backgroundColor if textColor? element.style.color = textColor ``` 然后在頁面中這么做: ``` <a href="#" onclick="paintIt(this, '#990000')">Paint it red</a> ``` 這種方法好點兒,但是如果很多鏈接需要同樣的效果該怎么辦呢? ``` <a href="#" onclick="paintIt(this, '#990000')">Paint it red</a> <a href="#" onclick="paintIt(this, '#009900', '#FFFFFF')">Paint it green</a> <a href="#" onclick="paintIt(this, '#000099', '#FFFFFF')">Paint it blue</a> ``` 非常不符合 DRY 原則。為了解決這個問題,我們可以使用“事件”。在鏈接上添加一個 `data-*` 屬性,然后把處理程序綁定到擁有這個屬性的點擊事件上: ``` paintIt = (element, backgroundColor, textColor) -> element.style.backgroundColor = backgroundColor if textColor? element.style.color = textColor $ -> $("a[data-background-color]").click -> backgroundColor = $(this).data("background-color") textColor = $(this).data("text-color") paintIt(this, backgroundColor, textColor) ``` ``` <a href="#" data-background-color="#990000">Paint it red</a> <a href="#" data-background-color="#009900" data-text-color="#FFFFFF">Paint it green</a> <a href="#" data-background-color="#000099" data-text-color="#FFFFFF">Paint it blue</a> ``` 我們把這種方法稱為“非侵入式 JavaScript”,因為 JavaScript 代碼不再和 HTML 混用。我們把兩中代碼完全分開,這么做易于修改功能。我們可以輕易地把這種效果應用到其他鏈接上,只要添加相應的 `data` 屬性就行。所有 JavaScript 代碼都可以放在一個文件中,進行壓縮,每個頁面都使用這個 JavaScript 文件,因此只在第一次請求時加載,后續請求會直接從緩存中讀取。“非侵入式 JavaScript”帶來的好處太多了。 Rails 團隊極力推薦使用這種方式編寫 CoffeeScript 和 JavaScript,而且你會發現很多代碼庫都沿用了這種方式。 ### 3 內建的幫助方法 Rails 提供了很多視圖幫助方法協助你生成 HTML,如果想在元素上實現 Ajax 效果也沒問題。 因為使用的是非侵入式 JavaScript,所以 Ajax 相關的幫助方法其實分成兩部分,一部分是 JavaScript 代碼,一部分是 Ruby 代碼。 [rails.js](https://github.com/rails/jquery-ujs/blob/master/src/rails.js) 提供 JavaScript 代碼,常規的 Ruby 視圖幫助方法用來生成 DOM 標簽。rails.js 中的 CoffeeScript 會監聽這些屬性,執行相應的處理程序。 #### 3.1 `form_for` [`form_for`](http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for) 方法協助編寫表單,可指定 `:remote` 選項,用法如下: ``` <%= form_for(@post, remote: true) do |f| %> ... <% end %> ``` 生成的 HTML 如下: ``` <form accept-charset="UTF-8" action="/posts" class="new_post" data-remote="true" id="new_post" method="post"> ... </form> ``` 注意 `data-remote="true"` 屬性,現在這個表單不會通過常規的提交按鈕方式提交,而是通過 Ajax 提交。 或許你并不需要一個只能填寫內容的表單,而是想在表單提交成功后做些事情。為此,我們要綁定到 `ajax:success` 事件上。處理表單提交失敗的程序要綁定到 `ajax:error` 事件上。例如: ``` $(document).ready -> $("#new_post").on("ajax:success", (e, data, status, xhr) -> $("#new_post").append xhr.responseText ).on "ajax:error", (e, xhr, status, error) -> $("#new_post").append "<p>ERROR</p>" ``` 顯然你需要的功能比這要復雜,上面的例子只是個入門。關于事件的更多內容請閱讀 [jquery-ujs 的維基](https://github.com/rails/jquery-ujs/wiki/ajax)。 #### 3.2 `form_tag` [`form_tag`](http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#method-i-form_tag) 方法的功能和 `form_for` 類似,也可指定 `:remote` 選項,如下所示: ``` <%= form_tag('/posts', remote: true) do %> ... <% end %> ``` 生成的 HTML 如下: ``` <form accept-charset="UTF-8" action="/posts" data-remote="true" method="post"> ... </form> ``` 其他用法都和 `form_for` 一樣。詳細介紹參見文檔。 #### 3.3 `link_to` [`link_to`](http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to) 方法用來生成鏈接,可以指定 `:remote`,用法如下: ``` <%= link_to "a post", @post, remote: true %> ``` 生成的 HTML 如下: ``` <a href="/posts/1" data-remote="true">a post</a> ``` 綁定的 Ajax 事件和 `form_for` 方法一樣。下面舉個例子。加入有一個文章列表,我們想只點擊一個鏈接就刪除所有文章,視圖代碼如下: ``` <%= link_to "Delete post", @post, remote: true, method: :delete %> ``` CoffeeScript 代碼如下: ``` $ -> $("a[data-remote]").on "ajax:success", (e, data, status, xhr) -> alert "The post was deleted." ``` #### 3.4 `button_to` [`button_to`](http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-button_to) 方法用來生成按鈕,可以指定 `:remote` 選項,用法如下: ``` <%= button_to "A post", @post, remote: true %> ``` 生成的 HTML 如下: ``` <form action="/posts/1" class="button_to" data-remote="true" method="post"> <div><input type="submit" value="A post"></div> </form> ``` 因為生成的就是一個表單,所以 `form_for` 的全部信息都適用于這里。 ### 4 服務器端處理 Ajax 不僅需要編寫客戶端代碼,服務器端也要做處理。Ajax 請求一般不返回 HTML,而是 JSON。下面詳細介紹處理過程。 #### 4.1 一個簡單的例子 假設在網頁中要顯示一系列用戶,還有一個新建用戶的表單,控制器的 `index` 動作如下所示: ``` class UsersController < ApplicationController def index @users = User.all @user = User.new end # ... ``` `index` 動作的視圖(`app/views/users/index.html.erb`)如下: ``` <b>Users</b> <ul id="users"> <%= render @users %> </ul> <br> <%= form_for(@user, remote: true) do |f| %> <%= f.label :name %><br> <%= f.text_field :name %> <%= f.submit %> <% end %> ``` `app/views/users/_user.html.erb` 局部視圖如下: ``` <li><%= user.name %></li> ``` `index` 動作的上部顯示用戶,下部顯示新建用戶的表單。 下部的表單會調用 `UsersController` 的 `create` 動作。因為表單的 `remote` 屬性為 `true`,所以發往 `UsersController` 的是 Ajax 請求,使用 JavaScript 處理。要想處理這個請求,控制器的 `create` 動作應該這么寫: ``` # app/controllers/users_controller.rb # ...... def create @user = User.new(params[:user]) respond_to do |format| if @user.save format.html { redirect_to @user, notice: 'User was successfully created.' } format.js {} format.json { render json: @user, status: :created, location: @user } else format.html { render action: "new" } format.json { render json: @user.errors, status: :unprocessable_entity } end end end ``` 注意,在 `respond_to` 的代碼塊中使用了 `format.js`,這樣控制器才能處理 Ajax 請求。然后還要新建 `app/views/users/create.js.erb` 視圖文件,編寫發送響應以及在客戶端執行的 JavaScript 代碼。 ``` $("<%= escape_javascript(render @user) %>").appendTo("#users"); ``` ### 5 Turbolinks Rails 4 提供了 [Turbolinks gem](https://github.com/rails/turbolinks),這個 gem 可用于大多數程序,加速頁面渲染。 #### 5.1 Turbolinks 的工作原理 Turbolinks 為頁面中所有的 `&lt;a&gt;` 元素添加了一個點擊事件處理程序。如果瀏覽器支持 [PushState](http://dwz.cn/pushstate),Turbolinks 會發起 Ajax 請求,處理響應,然后使用響應主體替換原始頁面的整個 `&lt;body&gt;` 元素。最后,使用 PushState 技術更改頁面的 URL,讓新頁面可刷新,并且有個精美的 URL。 要想使用 Turbolinks,只需將其加入 `Gemfile`,然后在 `app/assets/javascripts/application.js` 中加入 `//= require turbolinks` 即可。 如果某個鏈接不想使用 Turbolinks,可以在鏈接中添加 `data-no-turbolink` 屬性: ``` <a href="..." data-no-turbolink>No turbolinks here</a>. ``` #### 5.2 頁面內容變更事件 編寫 CoffeeScript 代碼時,經常需要在頁面加載時做一些事情。在 jQuery 中,我們可以這么寫: ``` $(document).ready -> alert "page has loaded!" ``` 不過,因為 Turbolinks 改變了常規的頁面加載流程,所以不會觸發這個事件。如果編寫了類似上面的代碼,要將其修改為: ``` $(document).on "page:change", -> alert "page has loaded!" ``` 其他可用事件等詳細信息,請參閱 [Turbolinks 的說明文件](https://github.com/rails/turbolinks/blob/master/README.md)。 ### 6 其他資源 下面列出一些鏈接,可以幫助你進一步學習: * [jquery-ujs 的維基](https://github.com/rails/jquery-ujs/wiki) * [其他介紹 jquery-ujs 的文章](https://github.com/rails/jquery-ujs/wiki/External-articles) * [Rails 3 遠程鏈接和表單權威指南](http://www.alfajango.com/blog/rails-3-remote-links-and-forms/) * [Railscasts: Unobtrusive JavaScript](http://railscasts.com/episodes/205-unobtrusive-javascript) * [Railscasts: Turbolinks](http://railscasts.com/episodes/390-turbolinks) ### 反饋 歡迎幫忙改善指南質量。 如發現任何錯誤,歡迎修正。開始貢獻前,可先行閱讀[貢獻指南:文檔](http://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#contributing-to-the-rails-documentation)。 翻譯如有錯誤,深感抱歉,歡迎 [Fork](https://github.com/ruby-china/guides/fork) 修正,或至此處[回報](https://github.com/ruby-china/guides/issues/new)。 文章可能有未完成或過時的內容。請先檢查 [Edge Guides](http://edgeguides.rubyonrails.org) 來確定問題在 master 是否已經修掉了。再上 master 補上缺少的文件。內容參考 [Ruby on Rails 指南準則](ruby_on_rails_guides_guidelines.html)來了解行文風格。 最后,任何關于 Ruby on Rails 文檔的討論,歡迎到 [rubyonrails-docs 郵件群組](http://groups.google.com/group/rubyonrails-docs)。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看