zoukankan      html  css  js  c++  java
  • ROR问题(转载)

    转载 http://blog.csdn.net/aabbcc456aa/article/details/7482349

    本章目錄

    • Asset 靜態檔案
    • 第一種方式:替換 HTML 片段
    • 第二種方式:使用 JavaScript 腳本
    • 第三種方式:使用 JSON 資料格式
    • Ajax 表單
    • Ajax 按鈕
    • 關於除錯

    Assets 與 Ajax 應用程式

    Assets靜態檔案

    Assets指的是JavaScriptStylesheets和圖檔等靜態檔案,這些檔案並不會隨Requests不同而有所不同。而在Rails目錄中,只有public這個目錄是公開讀取的,所以通常我們會將靜態檔案都放在public這個目錄下,好讓瀏覽器可以直接讀取。但是隨著JavaScriptStylesheet檔案越來越多時,如何管理這些檔案變為一項議題,為了加快瀏覽器的下載速度,我們會合併JavaScriptStylesheet檔案,來減少瀏覽器Request下載次數。更進一步的還會壓縮這些檔案來加速下載時間。像是Yahoo!Google都有各自開源出自己的壓縮工具YUI CompressorClosure Compiler

    Rails 3.1引進了一項新功能叫做Assets pipeline,這個功能可以讓我們突破public目錄限制,可以將靜態檔案依需求放在不同目錄下,Rails會幫你組合並壓縮起來。特別是有一些Rails的外掛套件需要使用JavaScript等靜態檔案,在沒有這個功能之前,我們必須將JavaScript等檔案複製放在public目錄下,這樣瀏覽器才能讀取的到。

    Rails 3.1之前版本想要有類似的功能,筆者推薦可以安裝Jammit這套工具來管理Assets。如果是升級到3.1的話,記得在config/application.rb中加上config.assets.enabled = true才會啟用這個功能。

    Assets的位置在app/assets/下,首先最重要的就是app/assets/javascripts/application.jsapp/assets/stylesheets/application.css,這兩個檔案看起來充滿註解,其實它是個manifest檔案,列出了所有要載入的靜態檔案,這些檔案的位置依照慣例放在app/assetsvendor/assets目錄下。

    讓我們先看看application.js

    // This is a manifest file that'll be compiled into including all the files listed below.
    // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
    // be included in the compiled file accessible from http://example.com/assets/application.js
    // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
    // the compiled file.
    //
    //= require jquery
    //= require jquery_ujs
    //= require_tree .

    其中的require_jqueryrequire_jquery_ujs會載入JQueryRailsJQuery adapater,這是因為我們在Gemfile中有裝jquery-rails這個套件,所以這裡可以讀取的到。而require_tree .會載入這個目錄下的所有JavaScript檔案。總之,這個manifest的最後輸出結果就是通通壓縮成一個application.js檔案。

    同理application.css也是一樣載入所有stylesheets目錄下的CSS檔案,最後壓縮成application.css

    /*
     * This is a manifest file that'll automatically include all the stylesheets available in this directory
     * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
     * the top of the compiled file, but it's generally better to create a new file per style scope.
     *= require_self
     *= require_tree . 
    */

    讓我們看看View,在Layout檔案中:

    <%= stylesheet_link_tag    "application" %>
    <%= javascript_include_tag "application" %>

    因為最後輸出都壓縮成一個檔案了,所以這裡只需要載入application.cssapplication.js

    如何處理圖片

    放在app/assets/images下的圖片該怎麼使用呢?在實際佈署後,Rails會將檔案名稱加以編碼,例如rails.png會變成rails-bd9ad5a560b5a3a7be0808c5cd76a798.png。這麼做的原因是當圖片有變更的時候,編碼就會不同而有不同的檔名,這樣就可以避免瀏覽器快取到舊的檔案。也因為檔案名稱會變動,所以放在app/assets/images下的圖片,要用的時候就沒有辦法寫死檔名。在一般的View中,可以使用image_tag這個Helper

    <%= image_tag("rails.png") %>

    如果在CSS裡的話,有兩種辦法:一是將檔案命名為erb結尾,例如app/assets/stylesheets/main.css.erb,然後使用asset_path這個Helper

    h1 {
      background-image: url('<%= asset_path("rails.png") %>');
    }

    另一種方法是使用SassSCSS語法。其中SCSS相容於CSS。例如命名為app/assets/stylesheets/main.css.scss,然後使用image-url這個Sass提供的方法:

    h1 {
        background-image: image-url("rails.png")
    }

    如果是js檔案中想要拿圖片的位置,就只能用js.erb的格式,然後內嵌asset_path Helper方法了。

    Precompile編譯靜態檔案

    放在app/assets目錄下的AssetsRails支援使用不同的語法,例如使用Sass語法產生CSSCoffeeScript產生JavaScript,或是用ERb樣板也可以。使用的方法是將附檔名命名成.css.sass.css.scss.js.coffee.css.erb.js.erbRails就會編譯出結果給瀏覽器。

    Sass是一種CSS3語法的擴充,可以使用巢狀、變數、混入、選擇子繼承等等功能,可以更有效率有彈性的撰寫StylesheetSass最後會編譯出合法的CSS讓瀏覽器使用。使用上它區分成兩種形式的語法scsssass,前者可以與現有的css程式碼直接混合在一起,後者則透過縮排來省略了大括號{}(就像Python用縮排一樣)。CoffeeScript也是類似原理,它是一種迷你的程式語言,編譯之後會輸出可讀性高、符合JavaScript Lint規範的JavaScript程式碼。

    學習這兩種新語法需要額外的時間投入,但是對需要常常撰寫CSSJavaScript的設計師來說,應該是很不錯的工具,讀者可以自行斟酌是否採用。如果你不打算使用的話,可以編輯Gemfile拿掉以下:

    gem 'sass'
    gem 'coffee-script'

    如果採用Sass的話,推薦還可以採用Compass這套CSS框架的框架。

    編譯出最後結果

    開發的時候,Rails會自動將Asset的壓縮結果快取在tmp下,所以開發者不需要特別處理。但是實際正式上線時,最後壓縮的檔案還是必須放在public目錄下由網頁伺服器直接提供(或是由CDN)效能較好,以下的rake指令可以產生出來:

    rake assets:precompile

    產生出來的檔案在public/assets/下。

    rake assets:clean

    這樣就會刪除。

    注意,如果在開發模式下執行了rake assets:precompile,那麼因為放在public/assets/下的靜態檔案會優先丟給瀏覽器,所以這時候再修改app/assets下的原始碼會沒有作用。所以,開發時請記得要刪除這個目錄。

    不過,如果你有很多靜態檔案的話,開發模式下每次都要重新編譯太辛苦了。你可以先compile一次,然後把public/assets/下目前正在開發的檔案砍掉即可。

    如何拆成數個壓縮檔

    上述的application.jsapplication.css中,預設會壓縮所有app/assets目錄下的檔案,如果你需要拆開,只需要修改其中的內容把require_tree那行移除,那麼就只會壓縮你所指定的目錄或檔案。

    例如,要新增新的Manifest檔案的話,假設叫做app/assets/javascripts/search.js,內容如:

    //= require ./foobar

    這樣就會將assets/javascripts/foobar這個目錄下的檔案通通壓縮成search.js,而在View中:

    <%= javascript_include_tag "application" %>
    <%= javascript_include_tag "search" %>

    就會載入。注意到如果啟用了assets功能,javascript_include_tag只能接受一個參數,即Manifest檔案的名稱。

    為了讓rake assets:precompile也能產生新的壓縮檔案,你還需要編輯config/environments/production.rb加入:

    config.assets.precompile += %w( search.js )

    如何關閉這個功能

    也可以不使用這個功能,請修改config/application.rb將以下設定改成false

    config.assets.enabled = false

    這樣的話,在View中就必須列出所有你要載入的Script檔案:

    <%= stylesheet_link_tag    "reset", "application", :cache => "all" %>
    <%= javascript_include_tag 'jquery', 'rails', 'application', :cache => "all" %>

    這些檔案都必須放在public目錄下。而加上cache參數Rails會合併這些檔案,但是並不會壓縮。

    Ajax

    AjaxAsynchronous JavaScript and XML的縮寫,是一種不需要重新整理頁面,透過JavaScript來與伺服器交換資料、更新網頁內容的技術。目的在於改善使用者的操作介面,提昇流暢度。它主要是透過瀏覽器提供的XMLHttpRequestObject來達成,不過因為跨瀏覽器的困難度,大多數人們會選擇使用JavaScript Library來處理Ajax,例如JQueryYUI等。雖然Ajax的縮寫中包括XML,但是實務上並不一定要用XML格式,事實上也已經很少人使用XML當作傳輸的格式了。總歸來說,依照Ajax使用的格式分類,有三種方式:

    • 向伺服器請求 HTML 片段,然後客戶端瀏覽器上的 JavaScript 再替換掉頁面上的元素
    • 向伺服器請求 JavaScript 程式腳本,然後客戶端瀏覽器執行它
    • 向伺服器請求 JSON 或 XML 資料格式,然後客戶端瀏覽器的 JavaScript 解析後再動作。

    第一種方式非常簡單,但是限制是一次只能更新一小塊內容。Rails 比較常見使用第二種方式,容易使用彈性又大。而第三種方式則將 JavaScript 程式都放在客戶端瀏覽器上,相較於第二種則多了解析 JSON 或 XML 的部份。以Web API的設計角度來看,與表現層無關的JSON格式是比較乾淨的,可以獲得比較好的重複使用性。

    講解JavaScriptJQuery語法已經超過本書範圍,本章接下來會假設讀者已經有基本認識。身為一個Web程式設計師,不得不對JavaScript要有基本了解。

    Unobtrusive JavaScript

    Rails 從 3.0 開始將支援AjaxJavaScript都改成用Unobtrusive JavaScript(UJS)的方式。什麼是Unobtrusive呢? 用個範例來說吧:

    link_to 'Remove', event_path(1), :method => :delete

    Rails 3之前,會輸出:

    <a onclick="var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);f.submit();return false;" href="/events/1">Remove</a>

    Rails 3之後,會輸出:

    <a rel="nofollow" data-method="delete" class="delete" href="/events/1">Remove</a>

    Unobtrusive也就是將JavaScript程式與HTML完全分開了。

    第一種方式:替換 HTML 片段

    編輯 app/views/events/index.html.erb 最下方加入:

    <%= link_to "say hello", { :controller => "welcome", :action => "say" }, :id => "ajax-load"  %>
    <div id="content">
    </div>
    
    <script type="text/javascript" charset="utf-8">
        $(document).ready(function() {
            
            $('#ajax-load').click( function(){
                $('#content').load( $(this).attr("href") );
                return false;
            });
            
        });
    </script>

    第二種方式:使用 JavaScript 腳本

    編輯 app/views/events/index.html.erb,在迴圈中間加入

    <%= link_to 'ajax show', event_path(event), :remote => true, "data-type" => "script" %>

    編輯 app/controllers/events_controller.rb,在 show action 中加入

    respond_to do |format|
      format.html
      format.js
    end	

    新增 app/views/events/_event.html.erb,內容與 show.html.erb 相同

    新增 app/views/events/show.js.erb,內容如下

    $('#content').html("<%= escape_javascript(render :partial => 'event') %>")
                 .css({ backgroundColor: '#ffff99' });

    瀏覽 http://localhost:3000/events

    escape_javascript()可以縮寫為j()

    j()Rails 3.1之後版本才有

    第三種方式:使用 JSON 資料格式

    JavaScript Object Notation(JSON)是一種源自JavaScript的資料格式,是目前Web應用程式之間的準標準資料交換格式,在Rails之中,每個物件都有to_json方法可以很方便的轉換資料格式。 (TODO)

    <%= link_to 'ajax show', event_path(event), :remote => true, "data-type" => :json, :id => "update_foobar" %>

    點擊ajax show就會送出Ajax request了,但接下來要怎麼撰寫處理JSON的程式呢?

    $(function() {
        $('#update_foobar').bind("ajax:success", function(event, data) {            
            var foobar = $('#foobar');
            foobar.html( data.foobar_number );
        });
    });

    當然,你也可以把HTML片段當做JSON的資料來傳遞。

    另一種JSON的變形是JSONP(JSON with Padding),將JSON資料包在一個JavaScript function裡,這個做的用處是讓這個API可以跨網域被呼叫。要回傳JSONP格式,只需要在render :json時多一個參數是:callback即可

    respond_to do |format|
      format.json { render :json => @user.to_json, :callback => "process_user" }
    end

    或是使用Rack::JSONP這個Middleware,只要有?callback=參數就會自動變成JSONP。等同於上述使用:callback => params[:callback]

    Ajax 表單

    除了超連結 link_to 加上 :remote 可以變成 Ajax 之外,表單 form_for 也可以加上 :remote 變成 Ajax。

    form_for(@user, :remote => true

    Ajax 按鈕

    同理於超連結 link_to,按鈕 button_to 加上 :remote => true 參數也會變成 Ajax。

    關於除錯

    使用 Ajax 後,因為頁面沒有經過重新整理,發送的 request 請後是在背景執行的,所以在除錯的時候需要有額外的工具來協助我們觀察 JavaScript 運作的情形。推薦您安裝Firefox 瀏覽器以及 Firebug 這套工具。在SafariChrome也有內建類似Firebug的開發工

  • 相关阅读:
    ICON 收集
    vs2015with_update_3
    文件大全,以后就从这些格式入手fuzz
    诗词
    tools URL 收集
    (四)ORBSLAM运动估计
    (三)ORB特征匹配
    (二)ORB描述子提取源码思路与实现
    (一)ORB描述子提取
    双目立体匹配——归一化互相关(NCC)
  • 原文地址:https://www.cnblogs.com/wws19125/p/3036653.html
Copyright © 2011-2022 走看看