ajax交互式網(wǎng)頁應(yīng)用4.on rails進階篇-1前言_第1頁
ajax交互式網(wǎng)頁應(yīng)用4.on rails進階篇-1前言_第2頁
ajax交互式網(wǎng)頁應(yīng)用4.on rails進階篇-1前言_第3頁
ajax交互式網(wǎng)頁應(yīng)用4.on rails進階篇-1前言_第4頁
ajax交互式網(wǎng)頁應(yīng)用4.on rails進階篇-1前言_第5頁
已閱讀5頁,還剩17頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、將刪除改成自行綁事件貼文無限捲軸使用核選方塊( checkbox) 將刪除改成自行綁事件貼文無限捲軸使用核選方塊( checkbox) 做開關(guān)使用下拉選單( select) 分類貼文另外,搭配 jQuery Plugin 的話,也必須自己寫 Ajax 代碼。這章最后也會示范使用jQuery Raty - A Star Rating Plugin 來做評等。4-1 前言這一章將示范直接用 jQuery 的 Ajax 功能,而不使用 Rails 的 remote = true 方法來做 Ajax 效果。這是因為 Rails 的 remotetrue 功能只能放在超連結(jié)或表單上,因此不屬于這兩種情形

2、的需求,就需要自行綁事件上去,觸發(fā)時送 Ajax Request 到服務(wù)器。這一章將示范: 4-把刪除改成自行綁事件用 Rails 內(nèi)建的 remote = true 來幫送 Ajax,這背后的原理其實就上一章是自己去綁定事件,然后送 Ajax來改寫看看如何自行綁事件送 Ajax,首先修改 t.html.erb,刪掉本來接下來的 :method去:app/views/和 remote 行為,補上一個 delete-t class4-把刪除改成自行綁事件用 Rails 內(nèi)建的 remote = true 來幫送 Ajax,這背后的原理其實就上一章是自己去綁定事件,然后送 Ajax來改寫看看如何自

3、行綁事件送 Ajax,首先修改 t.html.erb,刪掉本來接下來的 :method去:app/views/和 remote 行為,補上一個 delete-t class 等會綁事件上ts/t.html.erb- %ger,+ true % Delete,t_path(t), :method = :delete, :class= btn btn-dant_path(t), :class = deletet btn btn-danger % 然后在 appviews/tsindexhtmlerb 下方加入:app/views/ts/index.html.erb/ 這會綁click 事件到所有有

4、 .delete-t class 的元素上,也就是所有的刪除按+結(jié)的+$(.deletet).click(function(evt)/ evt 是瀏覽器的事件物件, evtpreventDefault(); 會終止這個元素的默認(rèn)行為:/ 超連結(jié) a 的默認(rèn)行為是跳到下一頁,如果沒有這行的話,送出 ajax 后會跳去 sho evtpreventDefault();ge/ this 是個特別的變量, 代表觸發(fā)事件的元素。使用 attr 可以元素的屬性, 這里要拿到超連var url = $(this).attr(href);/ 送出 Ajax$.ajax( url: url,method: DE

5、LETE,daypescript / 要求服務(wù)器回傳 javascript) ) 一但需要自己端綁事件, 就會覺得把 JavaScript代碼集中端的話, 責(zé)任區(qū)分來改成用 JSONdaype 改成 JSON,然后加一會比較清楚。因此格式吧,把個 sucapp/views/ssucs 的函式:的回呼,服務(wù)器回傳資料后,就會觸發(fā)ts/index.html.erb$(.deletet).click(function(evt)evt.preventevt.preventDefault();var url = $(this).attr(href);/ 送出 Ajax$.ajax( url: url,m

6、ethod: DELETE, daype: scriptdaypejson, / 要求服務(wù)器回傳 jsonsucs: functiondata)/ data 就是服務(wù)器回傳的 JSON 資料$(#t- + dataid).remove();) ) 修改 app/controllers/ts_controller.rb 改成直接回傳 JSONapp/controllers/ts_controller.rbdef destroyt = current_usosts.find(params:id) t.destroyrender :json = :id = t.id end 接著刪除 app/vie

7、ws/ts/destroy.js.erb 樣板不需要 Remote JavaScript 了如果團隊中有專門的前端工程師,也會偏好這種方式。這樣前后端的工作可以拆分的比較清楚。后端處理數(shù)據(jù)庫和回傳 JSON 資料即可,頁面怎么變化全由前端工程師負(fù)責(zé)。4-貼文無限捲軸目標(biāo):實作貼文的無限捲軸 (Endless Page),當(dāng)用戶捲到畫面最下方時,自動加載更早的資料。這個任務(wù)需要偵測瀏覽器捲軸的行為,沒辦法用 remotetrue 了,需要自己去綁定= 事件,偵測用戶捲到視窗最下面。編輯 appviews/ts/index.html.erbapp/views/ts/index.html.erb+4

8、-貼文無限捲軸目標(biāo):實作貼文的無限捲軸 (Endless Page),當(dāng)用戶捲到畫面最下方時,自動加載更早的資料。這個任務(wù)需要偵測瀏覽器捲軸的行為,沒辦法用 remotetrue 了,需要自己去綁定= 事件,偵測用戶捲到視窗最下面。編輯 appviews/ts/index.html.erbapp/views/ts/index.html.erb+/ 記下目前畫面最小的貼文 ID var current_t_id = ;/ 當(dāng)捲軸動的時候,會觸發(fā)這個事件$(window).scroll(function()/ 當(dāng)捲到最下面的時候if (window.innerHeight + window.scr

9、ollY) = .body.offsetHeight) var url = / if (url) $.ajax(ts?max_id= + current_t_id;method: GET, url: url,daype: script) else console.log(data ended) ) 修改 appcontrollers/ts_controllerrb,跟之前做分頁一樣,繼續(xù)沿用了index action,只是會根據(jù) paramsmax_id 回傳更早的資料:app/controllers/ts_controller.rbdefindexts ts -+t.order(id DES

10、C).allt.order(id DESC).limit(20if params:max_idts = ts.where( id ?, params:max_id)+endrespond_to do format.html format.jsendend |format|# 如果客戶端要求 HTML,則回傳 indexhtmlerb# +endrespond_to do format.html format.jsendend |format|# 如果客戶端要求 HTML,則回傳 indexhtmlerb# 如果客戶端要求 JavaScript,回傳 indexjserbRails 根據(jù) req

11、uest 請求的格式在 $ajax respond_to 可以讓有指定了da新增ype),來回傳不同格式。app/views/ts/index.js.erb% $(#$(#ts.each do t| %t-list).append()t-list).append( t,:locals = t =t %);% end % if ts.any? %var current_% end %t_id = ;這樣畫面捲到最下方時,就會自動加載,并且更新 current_t_id 的值,這樣下次再抓就會抓到更早的資料。4-使用核選方塊(checkbox)做開關(guān)目標(biāo):做一個勾選的核選方塊,管理員可以打勾標(biāo)記成

12、。執(zhí)行 rails g migration add_flag_to_ts編輯 dbmigrate201704XX_add_flag_to_ts.rb201704XX_add_flag_to_ts.rbclass AddFlagTodef changets ActiveRecord:Migration54-使用核選方塊(checkbox)做開關(guān)目標(biāo):做一個勾選的核選方塊,管理員可以打勾標(biāo)記成。執(zhí)行 rails g migration add_flag_to_ts編輯 dbmigrate201704XX_add_flag_to_ts.rb201704XX_add_flag_to_ts.rbclas

13、s AddFlagTodef changets ActiveRecord:Migration5.0+add_column :users,:role, :string:flag_at, :datetimeadd_column : end end ts,執(zhí)行 rake dbmigrate編輯 apps/user.rbapp/s/user.rb+def is_admin? role = adminend執(zhí)行 rails console 新增一個管理員帳號User.create!( in = adminexle., :password=123456,:role = adm然后改用這個帳號登入。編輯 c

14、onfigroutesrb 新增一個 toggle_flag 路由:config/routes.rbresourmemberend end :dots dolike = ts#likeunlike = toggle_flagts#unlike+= ts#toggle_flagthtmlerb 加上 checkbox 核選方塊,以及顯示標(biāo)記時間:編輯 appviews/ts/是 change,表示輸入框有變動的話,就會觸發(fā)。以改寫成$(是 change,表示輸入框有變動的話,就會觸發(fā)。以改寫成$().on(click, function().) 是一樣的。這里用的事件名稱$(X).on 是綁事件

15、的語法,之前學(xué)過的 $().click(function(). app/views/ts/t.html.erbdiv classpanelbody 略)div class=panel-footer toggle_flag_t_path(tclasstogglefl ag % 標(biāo)記為 span id=t-flag- 編輯 app/views/ts/index.html.erb 綁上 click 事件送出 Ajax 請求app/views/ts/index.html.erb$(.toggle-flag).on(change, function()var url = $(this).data(url

16、);+$.ajax(url: url,method: T,daype: json,sucs: function(data)if ( dataflag_at ) $(#t-flag- + dataid).html(dataflag_at); else $(#t-flag- + dataid).html();););解說toggle_flag action最后編輯 app/controllers/ ts_controller.rb 新增一個接收處理:app/controllers/ts_controller. rb+def toggle_flagtoggle_flag action最后編輯 app

17、/controllers/ ts_controller.rb 新增一個接收處理:app/controllers/ts_controller. rb+def toggle_flag=t.find(params:id)if else end t.flag_at t.flag_at=nil t.flag_at=Time.nowt.save! render :json = :message = ok, :flag_at = t.flag_at, :id = t.id+end 最后成果:在 HTML 元素屬性上的 data-,在 jQuery 中可以用 .data() 它的值4-瀏覽器 Bubble U

18、p事件模型ug,就是剛新增的貼文沒作用。你可以試試看先新前述的刪除和打勾的例子,有個增一筆貼文,然后點點看刪除和打勾,會發(fā)現(xiàn)竟然沒作用。這是怎么回事呢? 這是因為瀏覽器并不會為新增的元素自動綁事件上去。所以后來Ajax 新增上去的貼文是沒有事件的。那要怎么解決呢需要了解一下瀏覽器的事件機制,假設(shè)有以下 HTML: click時,瀏覽器不只會觸發(fā) a 元素的 click 事件,也會往外層一4-瀏覽器 Bubble Up事件模型ug,就是剛新增的貼文沒作用。你可以試試看先新前述的刪除和打勾的例子,有個增一筆貼文,然后點點看刪除和打勾,會發(fā)現(xiàn)竟然沒作用。這是怎么回事呢? 這是因為瀏覽器并不會為新增的

19、元素自動綁事件上去。所以后來Ajax 新增上去的貼文是沒有事件的。那要怎么解決呢需要了解一下瀏覽器的事件機制,假設(shè)有以下 HTML: click時,瀏覽器不只會觸發(fā) a 元素的 click 事件,也會往外層一click 事件、div 的 click 事件、body 的 click 事件。這叫做當(dāng)點擊p 路觸發(fā),包括Bubble Up 事件模型。了解這個模型之后,就可以將事件綁在可靠的上一層元素上,這里也就是上,反正點擊里面的元素,最終都會 Bubble Up 上來觸發(fā)。#tlist 的 div請修改 appviews/ts/index.html.erbapp/views/ts/index.ht

20、ml.erbt).click(function(evt)-+$(.delete$(#t-list).on(click, .delete-t, function(evt)/ -+$(.toggle-flag).on(change, function()$(#t-list).on(change, .toggle-flag, function()一樣是用on 語法,但是改成綁在 tlist 上,以及重點是多了第二個參數(shù)可以過濾出真正觸發(fā)的元素,在這里也就是t 和 toggleflag.delete-先在外層記下t 是觸發(fā)事件的元素。closest 會找最近的上一層元素,這里就會找到包住整個貼文的 c

21、lass 是 panel的 div 區(qū)塊。繼續(xù)修改 先在外層記下t 是觸發(fā)事件的元素。closest 會找最近的上一層元素,這里就會找到包住整個貼文的 class 是 panel的 div 區(qū)塊。繼續(xù)修改 checkbox 開關(guān):app/views/ts/index.html.erb$(#var vart-list).on(change, .toggle_flag,function() url = $(this).data(url);t = this;+由于 sucs 是個異步的回呼,里面的 this 不等同于外層的 this。所4-6 使用jQuery Traversing走訪元上述的范例中

22、,有用到 this 可以知道是哪一個元素被點擊了,所以才可以用 $(this).data(url) 去到該元素的 data 屬性。既然已經(jīng)知道是哪一個元素被點擊了,那其實可以利用 jQuery 的 Traversing API,就可以進行定位: 例可以這樣修改刪除app/views/ts/index.html.erb$(#t-list).on(click, .delete-t,function(evt) evt.preventDefault();var url = $(this).attr(href);vart = this;$.ajax( url: url,method: DELETE, d

23、aype: json,sucs: function(data)$(#t- + dataid).remove();$(t).closest(.panel).remove();) /return false;) 解說:$.ajax( url: url,method: T,da sucifype: json,s: function($.ajax( url: url,method: T,da sucifype: json,s: function(data)( dataflag_at ) -+$(#$( else$(#$(t-flag- + dataid).html(dataflag_at);t).cl

24、osest(label).find(span).html(dataflag_at)t-flag- + dataid).html();t).closest(label).find(span).html()-+); ); 解說:find 會找下層的元素。一個常見的技巧是,先往上層找到共同的祖先是 label,然后往里層找目標(biāo) span這樣做的好處是什么呢? 這樣寫t id 到 div 上來定位了。透就不需要額外塞就可以走訪到要操作的 DOM 上。過點擊的元素,4-使用下拉選單(select)分類貼文目標(biāo):做一個下拉選單可以分類,選了就立即生效,不需要再點送出產(chǎn)生一個分類 Category t 貼文

25、屬于一種分類:讓,讓執(zhí)行rails g category編輯db/migrate/201704XX_create_categories.rbdb/migrate/201704class CreateCategoriesdef changeXX_create_categories.rb4-使用下拉選單(select)分類貼文目標(biāo):做一個下拉選單可以分類,選了就立即生效,不需要再點送出產(chǎn)生一個分類 Category t 貼文屬于一種分類:讓,讓執(zhí)行rails g category編輯db/migrate/201704XX_create_categories.rbdb/migrate/201704c

26、lass CreateCategoriesdef changeXX_create_categories.rb belongs_totrue略end 編輯 apps/category.rbapp/s/category.rbclass Category Ruby Category.create!( Category.create!( Category.create!(Category.create!(:name:name:name:name=JavaScript Java) 編輯 appviews/thtmlerb 加上下拉選單:ts/Category.create!( Category.crea

27、te!( Category.create!(Category.create!(:name:name:name:name=JavaScript Java) 編輯 appviews/thtmlerb 加上下拉選單:ts/app/views/ts/t.html.erbdiv%class=panel-footerif current_user & current_user.is_admin? %+p + :url = t_path(t) , :prompt= 請選擇分類, :class = select_category % 編輯 appviews/tsindex.html.erb 綁上事件:app/

28、views/ts/index.html.erb+$(#t-list).on(change, .select_category,var url = $(this).data(url);function()$.ajax( url: url,method: PATCH,daype: json,data: t: category_id:););$(this).val()其中$ajax 里面的就是要送出去的參數(shù),透過 $thisval()可以抓到選單的值。datats_controllerrb 加上 update action:編輯app/controllers/app/controllers/ts_c

29、ontroller.rb+defupdatet t.find(params:id)t.update!(t_params render :json = :id = t.id, :message = ok+end 略def t_params -+params.require(+end 略def t_params -+params.require(: params.require(: end t).permit(:content) t).permit(:content, :category_id) 最后成果:4-8 Ajax動畫效果上一節(jié)的下拉選單送出 Ajax 后,雖然數(shù)據(jù)庫已經(jīng)更新了,但是并沒有

30、任何視覺回饋,用戶可能會感到疑惑到底成功了沒有。所以通常戶操作確實完成了。還會制作一些動畫效果,好告訴用git讓圖找一張動畫可以產(chǎn)生和, 或用這張動( 請按右鍵另存新檔), 請將動圖請放在publicimages/ 目錄下, 并命名為ajaxloader.gif修改 appviews/ts/4-8 Ajax動畫效果上一節(jié)的下拉選單送出 Ajax 后,雖然數(shù)據(jù)庫已經(jīng)更新了,但是并沒有任何視覺回饋,用戶可能會感到疑惑到底成功了沒有。所以通常戶操作確實完成了。還會制作一些動畫效果,好告訴用git讓圖找一張動畫可以產(chǎn)生和, 或用這張動( 請按右鍵另存新檔), 請將動圖請放在publicimages/

31、目錄下, 并命名為ajaxloader.gif修改 appviews/ts/index.html.erbapp/views/ts/index.html.erb$(#var vart-list).on(change, .select_category,function() url = $(this).data(url);t = this;+$.ajax(url: url, method: PATCH,daype: json,data: t: category_id: $(this).val(), beforeSend: function()-+) +$(t).after( $( img src=

32、/images/ajax-loader.gifid=ajax-loading); , complete: function()$(#ajax-loading).remove();); ); 會在 Ajax 送出前觸發(fā),而 complete 會在完成后觸發(fā)。分別是其中 beforeSend這張動畫 gif,以及在 Ajax 完成后移除??梢詴簳r故意地在 action 做延遲:因為是本地開發(fā),感覺可能會一閃而過,app/controllers/ def update app/controllers/ def update sleep(1) 略 )end ts_controller.rb但這只是看看

33、效果,試完請移除掉。最后成果:修改 appassetsjavascriptapplicationjs修改 appassetsjavascriptapplicationjsapp/assets/javascript/application.js/= require jquery.raty/= require_tree 修改 appassetsstylesheetsapplicationscssimport bootstrap-sprockets; import bootstrap;+ import jquery.raty;如果你ootstrap 的話,這里是 application.css 修改

34、 app/views/ts/t.html.erbdiv class=panel-bodyspan id=t-thumbsup- class=label label-sucs 修改 app/views/ts/index.html.erb$(.raty).raty( path: /images/ );瀏覽畫面,應(yīng)該就會看看星星了,也可以點點看。但是目前還沒串好數(shù)據(jù)庫。/=require jquery.raty將 libjquery.ratycss 放到 vendorassetsstylesheets/ 目錄下將 libjquery.raty.js 放到 vendorassets/javascrip

35、ts/ 目錄下將 images 下,放在 public/images 目錄下4-9 jQuery Plugin整合示范目標(biāo): 使用 jQuery Raty 這個 jQuery Plugin,進行貼文的星星評等,并計算平均分?jǐn)?shù)。前往 /wbohos/raty 點選 Clone or download 按鈕,然后點 Download ZIP回來。解壓縮后:接下來希望點了星星評等,會實際進數(shù)據(jù)庫。接下來希望點了星星評等,會實際進數(shù)據(jù)庫。4-10 jQuery Plugin整合示范(cont)一個用戶可以針對很多貼文評分,一篇貼文也可以有多人評分,讓新增一個tScore 來分?jǐn)?shù):執(zhí)行 rails g

36、t_score修改 db/migrate201704XX_create_t_scores.rbdb/migrate/201704XX_create_t_scores. rbclass Createdef changetScores 4-10 jQuery Plugin整合示范(cont)一個用戶可以針對很多貼文評分,一篇貼文也可以有多人評分,讓新增一個tScore 來分?jǐn)?shù):執(zhí)行 rails g t_score修改 db/migrate201704XX_create_t_scores.rbdb/migrate/201704XX_create_t_scores. rbclass Createdef

37、 changetScores +t.t.t.eger egereger:true:score:user_id t.timest end end end 執(zhí)行 rake dbmigrate編輯 apps/t_score.rbapp/class+s/t_score.rbtScore tScoredef find_score(user)user & self.scores.where( :user_id = user.id end).+def average_score self.scores.average(:score)end編輯 configroutesrbconfig/routes.rbresourmemberend end :dots dolike = ts#like+def average_score self.s

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論