【第22期】观点:IT 行业加班,到底有没有价值?

[Ruby on Rails实战圣经]Ajax 应用程式

翻译 2016年06月02日 10:56:49

Ajax 应用程式

It's not a bug - it's an undocumented feature. - Unknown

AjaxAsynchronous JavaScript and XML的缩写,是一种不需要重新整理页面,透过JavaScript来与伺服器交换资料、更新网页内容的技术。目的在于改善使用者的操作介面,提升流畅度。它主要是透过浏览器提供的XMLHttpRequestObject来达成,不过因为跨浏览器的困难度,大多数人们会选择使用JavaScript Library来处理Ajax,例如JQuery。虽然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后将Ajax使用的JavaScript都改成Unobtrusive JavaScript(UJS)方式。什么是Unobtrusive呢?用个范例来说吧,它会将超连结改成用表单DELETE送出,并且用一个提示视窗来作确认:

link_to 'Remove', event_path(1), :method => :delete, :data => { :confirm => "Sure?" }

Rails 3之前,会输出:

<a onclick="if (confirm('Sure?')) { 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-confirm="Sure?" data-method="delete" class="delete" href="/events/1">Remove</a>

Unobtrusive也就是将JavaScript程式与HTML完全分开,除了可以让HTML码干净之外,也可以支援更换不同的JavaScript Library,例如把Rails内建的jQuery换成Protytype.jsangular.js等等。

Layout中有输出一段<%= csrf_meta_tag %>的作用就是搭配给UJS使用的,让JavaScript可以拿到CSRF安全验证码,我们会在安全一章讨论到什么是CSRF

Ajax 表单

除了 ​​超连结link_to加上:remote可以变成Ajax之外,表单form_for也可以加上:remote变成Ajax。

form_for @user, :remote => true

Ajax 按钮

同理于超连结link_to,按钮button_to加上:remote => true参数也会变成Ajax。

除了 ​​已经看过的:data => { :confirm => "Are you Sure?" }之外,disable_with可以避免使用者连续按下送出:

button_to "Remove", user_path(@user), :data => { :disable_with => 'Removing' }

第一种方式:替换HTML 片段

编辑app/views/events/index.html.erb 最下方加入:

<%= link_to 'Hello!', welcome_say_hello_path, :id => "ajax-load" %> <div id="content">
</div>

<script>
    $(document).ready(function() {
        $('#ajax-load').click( function(){
            $('#content').load( $(this).attr("href") );
            return false;
        });

    });
</script>

如此点下超连结后,就会把回传的HTML置入到<div id="content">里面。

第二种方式:使用JavaScript 脚本

编辑app/views/events/index.html.erb,在回圈中间加入

<%= link_to 'ajax show', event_path(event), :remote => true %>

在回圈外插入一个<div id="event_area"></div>

编辑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,内容如下

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

浏览http://localhost:3000/events

escape_javascript()可以缩写为j()

第三种方式:使用JSON 资料格式

JavaScript Object Notation(JSON)是一种源自JavaScript的资料格式,是目前Web应用程式之间的准标准资料交换格式,在Rails之中,每个物件都有to_json方法可以很方便的转换资料格式。

<%= link_to 'ajax show', event_path(event), :remote => true, :data => { :type => :json }, :class => "ajax_update" %>

点击ajax show就会送出Ajax request了,但接下来要怎么撰写处理JSON的程式呢?

<script>
$(document).ready(function() {
    $('.ajax_update').on("ajax:success", function(event, data) {
        var event_area = $('#event_area');
        event_area.html( data.name );
    });
});
</script>

当然,你也可以把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

事实上,Rails预设让每个换页都用上了Ajax技巧,这一招叫做Turbolinks,在预设的Gemfile中可以看到gem "turbolinks",以及Layout中的data-turbolinks-track

它的作用是让每一个超连结都只用Ajax的方式将整个body内容替换掉,这样换页时就不需要重新载入head部份的标签,包括JavaScriptCSS等等,目的是可以改善换页时的速度。

要特别注意因为它没有整页重新载入,所以如果有放在application.js里面的$(document).ready程式就变成只有第一次载入页面才执行到,换页时就失效了。这时候必须改成$(document).on("page:change", function(){ ...})

如果想要明显体会它的效果,可以在app/assets/javascripts/application.js里面加上

Turbolinks.enableProgressBar();

最后,因为它会影响JavaScriptEvent Bindings行为,所以在搭配一些JavaScript比较吃重的应用程式,例如使用JavaScript FrameworkBackboneAngularJSEmber时会移除不用,以免互相影响。

举报

相关文章推荐

推荐 书目《Ruby on Rails 實戰聖經 ---使用 Rails 3.2 及 Ruby 1.9.3》

Ruby on Rails 實戰聖經使用 Rails 3.2 及 Ruby 1.9.3 回首頁 關於作者 關於本書 常見問題 生態圈 我是ihower,本書介紹Ru...

Selenium Ruby on Rails and Ajax

验收测试(也称功能测试)是用来测试手工任务的功能的,但是手工测试这些任务可能很花时间,并且容易出现人为的错误。在本文中,作者为架构师、开发人员和测试人员展示了如何使用 Selenium 测试工具来自动化验收测试。通过自动化测试,可以节省时间,并消除测试人员所犯的错误。文中还给出了一个例子,以演示如何将 Selenium 应用到现实中使用 Ruby on Rails 和 Ajax 的项目上。   Web 应用程序的验收测试常常涉及一些手工任务,例如打开一个浏览器,并执行一个测试用例中所描述的操作。但是手工执行的任务容易出现操作人员人为的错误,也比较费时间。因此,尽可能将这些任务自动化,以消

Ruby on Rails 實戰聖經阅读(二)

1.操作系统 centos5.4 2.安装ruby yum install ruby 会安装得到 1.8.5 如果你公司用的是1.8.X就无所谓了, 拿这个学习就行了 如果你们公司用的是1.9.X,那...

zhuan//為Ruby on Rails程式加入拖曳排序功能~

来源: http://www.simplexteam.org/tips/ruby/77-ruby-on-rails-drag-and-drop-sort.html?tmpl=component&amp;print=1&amp;page=   要為Ruby on Rails程式加入拖曳排序功能~我們可以使用sortable_element helper function~ 他可近呼自動地為程式加入拖曳排序功能 這個程式中會用到acts_as_list插件,請先行安裝~ 我們現在先用scaffold建立基本CRUD功能~

Ruby on Rails 实战圣经 RAW online

http://ihower.tw/rails3/index.html 引用: 我是ihower,本書介紹Ruby on Rails這套開放原始碼的網站開發框架,預定於2011年下半年出版。如果您有任何意見或勘誤指教,不用怕是初學者(你的問題很可能也是其他新手會碰到的問題),都歡迎來信給我聯絡。 目前的撰寫進度:Part1已完成進入校稿階段,讀者可以照著練習,有任何問題歡迎和我反應。Part2各章已有草稿內容,讀者可以先行略讀。
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)