弦而時習之

Rails - Ajax and Backbone.JS

好像有一段時間沒寫網誌了!

上週在 Code School 週末免費最後的二十多小時才發現有免費課程,趕緊選了一個進行後,覺得不錯,於是跟老爸討論後決定購買會員資格。

經過一週的苦戰,總算是將十三個課程都全不上過一次。 (不過只看投影片跟進行練習題,沒有看影片,因為有點花時間,所以只能之後慢慢補完)

既然經過如此密集的訓練,功力想必大增,於是今天就來小試身手嘗試了 Rails 的 Ajax 與 Backbone.JS 的搭配。

下面目錄有錯誤之類的請見諒,因為正在練習靠印象打出來,真的有錯誤請通知一下會修正

Mission Initialize


首先,要先把專案環境配置出來。

我先切換到 MacOS 上超方便的 Pow 後,建立一個新專案。

接著建立一些基本的Model, Controller, View 等等……

接著設定好 config/router.rb

1
2
3
4
5

#略
root :to => "home#index"
resources :items, only: [:index]
#略

接著對 home, items controller 建立會用到的 method

1
2
3
4
5
#略
	def index

	end
#略
1
2
3
4
5
#略
	def index

	end
#略

到這邊基本上算是完成準備了!

Mission 01


首先,先來對 :remote 的 link 做測試(並沒有特別針對表單,不過原理大致相同)

1
2
3

<%= link_to("Items List", items_path, remote: true) %>

然後給 items#index 加個畫面。

1
2
3

There 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
2
3
4
5
6
7
8
#略
respond_to :html, :js

	def index
		@datas = Item.all
		respond_with(@datas)
	end
#略

再次打開點選連結,會發現 Ajax 雖然一樣傳回網頁,但是卻從包含 layout 變成剩下網頁內容了!

接著,補上 js 部分

1
2
3

$("body").text("You already clicked item list.");

這次點選連結後就會直接剩下 You already clicked item list. 這段文字。

看起來不錯,不過如果希望Ajax傳輸是回傳 JSON 格式,要怎麼處理呢?

Mission 02


稍微修改一下 home#index 的 view 讓連結變成傳回 JSON

1
2
3

<%= 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
4
5
6
7

#
//=require jquery
//=require jquery_ujs
//=require lib/underscore-min
//=require lib/backbone-min
#

這樣就不會先把 Backbone.JS 讀進來了~

然後用 CoffeeScript 來寫 Backbone.JS 的 MVC

這邊就很簡單的寫一下,沒有規劃,畢竟只是要測試看看會發生什麼事情 XDD

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

$ ->
	ItemModel = Backbeon.Model.extend()
	ItemCollection = Backbone.Collection.extend({
		url: '/items',
		model: ItemModel
	})
	
	ItemView = Backbone.View.extend({
		tagName: 'li',
		template: _.template("<strong><%= name %></strong>, <%= description %>"),
		render: ->
			$(@.el).html(@.template(@.model.toJSON()))
			return @
	})
	
	ItemViewList = Backbone.View.extend({
		tagName: 'ul',
		initialize: ->
			@.collection.on('reset', @.render, @)
		render: ->
			@.collection.forEach(@.addOne, @)
			return @
		addOne: (model)->
			itemView = new ItemView({model: model})
			@.$el.append(itemView.render().el)
	})

	items = new ItemCollection()
	itemList = new ItemViewList({collection: items})

	itemList.render()
	
	$("body").append("Items List")
	$("body").append(itemList.el)
	
	items.fetch()
	

今天最長的程式碼(笑)

接著打開網頁,就會發現 Items 被列出來了,看起來即使不另外設定也能夠自動讓 Rails 丟出 JSON 格式的資料。

大致上就是這樣了!不過 View 部分需要另外寫一個 template 其實不怎麼方便,如果用 Mission 01 的方法因為還是 erb 可以讓 Server 去 render :partial => “itemList” 之類的,不過 Backbone.JS 似乎就不怎麼方便。這部分只能看情況取捨摟~

做完 Code School 的課程真的有覺得內力大增,至少學到很多優秀的技巧。

Buy me a CoffeeBuy me a Coffee

電子報

留言