亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 3641 | 回復(fù): 0
打印 上一主題 下一主題

在Rails3時代js該怎么寫? [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2010-12-29 10:49 |只看該作者 |倒序瀏覽
本帖最后由 中關(guān)村村草 于 2010-12-29 11:08 編輯

[前注:本篇不是教程,只是一些rails的新技巧、特性的探討。]

Why?
現(xiàn)在,我們在進(jìn)行軟件、WEB項目開發(fā)時都用喜歡用框架,即省時省力,又有規(guī)有矩。所謂規(guī)矩,最常見的約束就是MVC三層分離,其中V是VIEW(視圖),而進(jìn)行WEB開發(fā)時,最常見的VIEW就是HTML頁面。HTML到了XHTML(http://en.wikipedia.org/wiki/XHTML)時代,也開始強(qiáng)調(diào)了要樣式與內(nèi)容結(jié)構(gòu)分離,“HCJ”三層分離,就是HTML(頁面內(nèi)容)、CSS(頁面裝飾)、JAVASCRIPT(頁面行為)塵歸塵土歸土,各自歸納到獨立的文件中,通過HTML的標(biāo)簽或?qū)傩詠磉M(jìn)行關(guān)聯(lián),最顯而易見的好處是一來方便代碼結(jié)構(gòu)化管理、解析,二來方便瀏覽器緩存。

我們很幸運(yùn)的,搭上了Rails這倆快車,一路走在流行技術(shù)的最前沿,在Rails3時代,Rails秉承“兼容并包”的良好品德和思想,在提供方便默認(rèn)配置之余,還放開了懷抱,使得更多更方便的框架、類庫可以集成進(jìn)來替換默認(rèn)配置。在Rails3中,Prototype這個js框架將不會默認(rèn)綁定(http://rails.uservoice.com/pages ... -unit-and-prototype)。


What?
在Rails3時代還沒到臨之前,如果不想用Prototype,可以有jRails(http://ennerchi.com/projects/jrails)代替,然后jRails是完全兼容PrototypeHelper(http://api.rubyonrails.org/class ... rototypeHelper.html),同樣會在HTML中嵌入JS代碼片段,從而傷害了HTML的純潔。為了要維護(hù)HTML的純潔以及JS的主權(quán)獨立,于是計算機(jī)之神說,要Unobtrusive,于是有了Unobtrusive_JavaScript(http://en.wikipedia.org/wiki/Unobtrusive_JavaScript)。

Unobtrusive_JavaScript簡單來說,就是把有指定元素行為的JS代碼分離出來,如事件描述:
分離前:
Html代碼
  1. <body>  
  2. <input type="text" name="date" onchange="validateDate(this);" />  
  3. </body>  
復(fù)制代碼
分離后:
Html代碼
  1. <head>
  2. <script>
  3. window.onload = function(){ //Wait for the page to load.
  4.     var inputs = document.getElementsByTagName('input');
  5.     for(var i=0,l=inputs.length;i<l;i++){
  6.         input = inputs[i];
  7.         if(input.name && input.name=='date'){
  8.             input.onchange = function(){
  9.                 validateDate(this);
  10.             }
  11.         }
  12.     }
  13. };

  14. function validateDate(){
  15.         //Do something when the content of the 'input' element with the name 'date' is changed.
  16. }
  17. </script>
  18. </head>
  19. <body>
  20. <input type="text" name="date" />
  21. </body>
復(fù)制代碼
把所有js綁定操作都統(tǒng)一放到頁面加載完再進(jìn)行。

How?
用一個比較常見的用戶信息修改操作為例,修改用戶的信息,一般會用如下代碼:
Ruby代碼
  1. <% form_for @user do |f| %>
  2.   <%= f.error_messages %>
  3.   <p>
  4.     <%= f.label :username %><br />
  5.     <%= f.text_field :username %>
  6.   </p>
  7.   <p><%= f.submit "Submit" %></p>
  8. <% end %>
復(fù)制代碼
會生成如下HTML代碼:
Html代碼
  1. <form action="/users/2" class="edit_user" id="edit_user_2" method="post"><div style="margin:0;padding:0"><input name="_method" type="hidden" value="put" /><input name="authenticity_token" type="hidden" value="ooDWeKPVumeI0r+O4E20g9TjfnxFKHp3ZsnCPCCrSFg=" /></div>
  2.   <p>
  3.     <label for="user_username">Username</label><br />
  4.     <input id="user_username" name="user[username]" size="30" type="text" value="rainchen" />
  5.   </p>
  6.   <p><input id="user_submit" name="commit" type="submit" value="Submit" /></p>
  7. </form>
復(fù)制代碼
如果要改為AJAX提交操作時,可以用remote_form_for helper(http://api.rubyonrails.org/class ... Helper.html#M001649),但這個其實是PrototypeHelper提供的一個輔助方法,把 form_for替換為remote_ form_for 后會在頁面中生成如下HTML代碼:
Html代碼
  1. <form action="/users/2" class="edit_user" id="edit_user_2" method="post" onsubmit="new Ajax.Request('/users/2', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">  
復(fù)制代碼
經(jīng)過之前的一番論述,現(xiàn)在的結(jié)論就是<form>標(biāo)簽不純潔了,被插了一段Prototype的AJAX代碼。

在Rails3時代,這種代碼是不和諧的,需要批判。

在解決這個問題前,先看一下在Rails3時代,類似AJAX請求場景,是怎樣實現(xiàn)的,如
Ruby代碼
  1. <%= link_to 'Users', users_path %>  
復(fù)制代碼
會生成HTML:
Html代碼
  1. <a href="/users">Users</a>  
復(fù)制代碼
用 remote_link_to 替換的話,將會得到:
Html代碼
  1. <a href="/users" data-remote="true">Users</a>  

復(fù)制代碼
被加進(jìn)了一個data-remote屬性,data-xxx 形式的屬性,在HTML5中是合理又合法的:http://ejohn.org/blog/html-5-data-attributes/

remote_link_to 其實是一個Rails3新的AjaxHelper的方法,實現(xiàn)代碼見:
http://github.com/rails/rails/bl ... pers/ajax_helper.rb

瀏覽代碼后,不難發(fā)現(xiàn)到今天為止,AjaxHelper 中還沒發(fā)現(xiàn)remote_form_for 的身影,也就是remote_form_for 還只是個傳說。

今天我們就是要嘗試實現(xiàn)這個傳說,讓我們就來見證奇跡。

在Rails3時代,沒有意外的話,<form>標(biāo)簽也會被插入 data-remote=“true" 這個標(biāo)記,因此思路很簡單,覆蓋掉remote_form_for 方法,加入這個標(biāo)記,然后在頁面加載后,用js查找?guī)в羞@個標(biāo)記的form,綁上AJAX操作即可。

1. 在application_helper.rb 中加入:
Ruby代碼
  1.   # unobtrusive javascript helpers
  2.   def remote_form_for(*args, &proc)
  3.       options = args.extract_options!
  4.       options[:html] ||= {}
  5.       options[:html]["data-remote"] = "true"
  6.       options[:html]["data-update"] = options[:update] unless options[:update].blank? # enable update the resposne data to *update* dom
  7.       args << options
  8.       form_for(*args, &proc)
  9.   end
復(fù)制代碼
2. 在js框架方面,我選擇用jquery
在layout中加入
Ruby代碼
  1. <%= javascript_include_tag respond_to?(:local_request?) && local_request? ? 'jquery.min' : 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js' %>
  2.     <%= javascript_include_tag respond_to?(:local_request?) && local_request? ? 'jquery-ui.min' : 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js' %>
  3.     <%= javascript_tag "AUTHENTICITY_TOKEN = '#{protect_against_forgery? ? form_authenticity_token : ""}';" %>
  4.     <%= javascript_include_tag 'application' %>
復(fù)制代碼
在application.js 中加入:
Js代碼
  1. $(function(){
  2.   // set authenticity koen for Rails
  3.   if(typeof AUTHENTICITY_TOKEN != 'undefined' && AUTHENTICITY_TOKEN != ''){
  4.     $.ajaxSetup( {data: {authenticity_token: AUTHENTICITY_TOKEN}} );
  5.   }

  6.   // setup app namespace
  7.   var app = {};

  8.   // show the ajax result
  9.    app.ajaxShowResult = function(options){
  10.     options = $.extend({title: '', body: '', width: 200, height: 200}, options);
  11.     if(!$("#app_ajax_result").get(0)){
  12.       $(document.body).append('<div id="app_ajax_result"></div>');
  13.       $("#app_ajax_result").dialog({
  14.         title: '',
  15.         bgiframe: true,
  16.         width: options.width,
  17.         height: options.height,
  18.         modal: true
  19.       });
  20.     }
  21.     $("#app_ajax_result").html(options.body);
  22.     $("#app_ajax_result").dialog('option', 'title', options.title);
  23.     return $("#app_ajax_result").dialog('open');
  24.    };

  25.   // default error handler for ajax request
  26.   app.ajaxError = function(XMLHttpRequest, textStatus, errorThrown){
  27.     return app.ajaxShowResult({title: XMLHttpRequest.statusText, body: XMLHttpRequest.responseText, width: 600, height: 400});
  28.   };

  29.   // default success handler for ajax request
  30.   app.ajaxSuccess = function(data, textStatus){
  31.     if(this.update){
  32.       $("#"+this.update).html(data);
  33.     }else if(this.dataType == 'html'){
  34.       return app.ajaxShowResult({title:textStatus, body: data});
  35.     }
  36.   };

  37.   app.ajax = function(options) {
  38.     $.ajax($.extend({ url : options.url, type : 'get', dataType: 'html', error: app.ajaxError, success: app.ajaxSuccess }, options));
  39.     return false;
  40.   };

  41.   // find all all data-remote tags
  42.   app.setupAjaxHelpers = function(){
  43.     // remote links handler
  44.     $('a[data-remote=true]').live('click', function() {
  45.       return app.ajax({ url : this.href });
  46.     });

  47.     // remote forms handler
  48.     $('form[data-remote=true]').live('submit', function() {
  49.       return app.ajax({ url : this.action, type : this.method, data : $(this).serialize(), update: $(this).attr('data-update') });
  50.     });
  51.   };

  52.     // init
  53.   app.init = function(){
  54.     app.setupAjaxHelpers();
  55.   };

  56.   app.init();

  57. });
復(fù)制代碼
關(guān)鍵代碼其實只是
Js代碼
  1.   // remote forms handler
  2.     $('form[data-remote=true]').live('submit', function() {
  3.       return app.ajax({ url : this.action, type : this.method, data : $(this).serialize(), update: $(this).attr('data-update') });
  4.     });
復(fù)制代碼
默認(rèn)用jquery-ui來做結(jié)果顯示。

3.要支持ajax方式獲取無layout的action rendered page時,還應(yīng)該在application_controller.rb里加入:
  1. #  render empty layout for ajax request
  2.   layout proc { |controller| controller.request.xhr? ? nil : 'application' }
復(fù)制代碼
后注:
1. 其中jquery的live事件還不是實現(xiàn)得很完整,對IE支持不好:

引用

jQuery is going to be adding support for .live("submit") in the next
release, and it's possible to emulate in rails.jquery.js in the interim.
-- Yehuda
On Tue, May 26, 2009 at 1:07 PM, meefs...@googlemail.com <

- Show quoted text -
--
Yehuda Katz
Developer | Engine Yard
(ph) 718.877.1325



2. 在HTML標(biāo)簽中是約定用css做標(biāo)記還是用屬性做標(biāo)記,篩選時會性能問題的差異,對我來說不是關(guān)注重點。

3. 在現(xiàn)在的Rails中使用Unobtrusive_JavaScript 版本的 remote_link_to 可參考:http://blog.solnic.eu/2009/09/08 ... -helpers-in-rails-3


參考:
http://blog.solnic.eu/2009/09/08 ... -helpers-in-rails-3
http://groups.google.com/group/r ... ad/3fa1cc2b1979a858
http://nutrun.com/weblog/unobtrusive-ajax-with-jquery-and-rails/
http://docs.jquery.com/Events/live

End?
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP