Rails - Ajax and Backbone.JS
好像有一段時間沒寫網誌了!
上週在 Code School 週末免費最後的二十多小時才發現有免費課程,趕緊選了一個進行後,覺得不錯,於是跟老爸討論後決定購買會員資格。
經過一週的苦戰,總算是將十三個課程都全不上過一次。 (不過只看投影片跟進行練習題,沒有看影片,因為有點花時間,所以只能之後慢慢補完)
既然經過如此密集的訓練,功力想必大增,於是今天就來小試身手嘗試了 Rails 的 Ajax 與 Backbone.JS 的搭配。
下面目錄有錯誤之類的請見諒,因為正在練習靠印象打出來,真的有錯誤請通知一下會修正
Mission Initialize
首先,要先把專案環境配置出來。
我先切換到 MacOS 上超方便的 Pow 後,建立一個新專案。
接著建立一些基本的Model, Controller, View 等等……
接著設定好 config/router.rb
1
2#略
3root :to => "home#index"
4resources :items, only: [:index]
5#略
接著對 home, items controller 建立會用到的 method
1#略
2 def index
3
4 end
5#略
1#略
2 def index
3
4 end
5#略
到這邊基本上算是完成準備了!
Mission 01
首先,先來對 :remote 的 link 做測試(並沒有特別針對表單,不過原理大致相同)
1
2<%= link_to("Items List", items_path, remote: true) %>
然後給 items#index 加個畫面。
1
2There is items list.
這樣一來就會有一個帶有 data-remote=“true” 屬性的連結產生。 (這方面還挺方便的,只要多加個 options 就轉職為 Ajax 了!)
接著打開 https://ajax-test.dev/ 點了一下連結,啥都沒發生。 於是打開 Chrome 的開發人員工具(Command + Alt + I)一探究竟。
確實,有 Ajax 請求,但是傳回的是 HTML 頁面,好像不太對。回想了一下 Code School 課程裡面有要增加 *.js.erb 之類的檔案,先去修改一下 Controller 讓他可以傳回 js 格式的檔案。
1#略
2respond_to :html, :js
3
4 def index
5 @datas = Item.all
6 respond_with(@datas)
7 end
8#略
再次打開點選連結,會發現 Ajax 雖然一樣傳回網頁,但是卻從包含 layout 變成剩下網頁內容了!
接著,補上 js 部分
1
2$("body").text("You already clicked item list.");
這次點選連結後就會直接剩下 You already clicked item list. 這段文字。
看起來不錯,不過如果希望Ajax傳輸是回傳 JSON 格式,要怎麼處理呢?
Mission 02
稍微修改一下 home#index 的 view 讓連結變成傳回 JSON
1
2<%= link_to("Items List", items_path, remote: true, "data-type" => "json") %>
再次點選連結,發現沒有被更改。 從開發人員面板看 Networks 的情況,有 Ajax 查詢發生,看一下回應: [ ] 類型是 JSON 看起來生效了,放點資料進去看看。
再次觀看時就發現有出現,不過頁面仍沒有變化。
這部分可以用 jQuery 去 bind 一些 UJS 的 Ajax 事件去做應對
Mission 03
接著再來把 Backbone.JS 放進去看看~
複製好檔案後來改 appication.js
1
2#略
3//=require jquery
4//=require jquery_ujs
5//=require lib/underscore-min
6//=require lib/backbone-min
7#略
這樣就不會先把 Backbone.JS 讀進來了~
然後用 CoffeeScript 來寫 Backbone.JS 的 MVC
這邊就很簡單的寫一下,沒有規劃,畢竟只是要測試看看會發生什麼事情 XDD
1
2$ ->
3 ItemModel = Backbeon.Model.extend()
4 ItemCollection = Backbone.Collection.extend({
5 url: '/items',
6 model: ItemModel
7 })
8
9 ItemView = Backbone.View.extend({
10 tagName: 'li',
11 template: _.template("<strong><%= name %></strong>, <%= description %>"),
12 render: ->
13 $(@.el).html(@.template(@.model.toJSON()))
14 return @
15 })
16
17 ItemViewList = Backbone.View.extend({
18 tagName: 'ul',
19 initialize: ->
20 @.collection.on('reset', @.render, @)
21 render: ->
22 @.collection.forEach(@.addOne, @)
23 return @
24 addOne: (model)->
25 itemView = new ItemView({model: model})
26 @.$el.append(itemView.render().el)
27 })
28
29 items = new ItemCollection()
30 itemList = new ItemViewList({collection: items})
31
32 itemList.render()
33
34 $("body").append("Items List")
35 $("body").append(itemList.el)
36
37 items.fetch()
38
今天最長的程式碼(笑)
接著打開網頁,就會發現 Items 被列出來了,看起來即使不另外設定也能夠自動讓 Rails 丟出 JSON 格式的資料。
大致上就是這樣了!不過 View 部分需要另外寫一個 template 其實不怎麼方便,如果用 Mission 01 的方法因為還是 erb 可以讓 Server 去 render :partial => “itemList” 之類的,不過 Backbone.JS 似乎就不怎麼方便。這部分只能看情況取捨摟~
做完 Code School 的課程真的有覺得內力大增,至少學到很多優秀的技巧。