顯示具有 ajax 標籤的文章。 顯示所有文章
顯示具有 ajax 標籤的文章。 顯示所有文章

3/27/2007

Ajax auto-update

Ajax 跟 Ruby on Rails 的整合已經眾所皆知,今天心血來潮,想來實做 digg-spy 形式的資料更新。但是我的需求是每隔一段固定的時間更新,而不是一直 append 新的訊息。在參考了幾個網站後,驚訝的發現,這種 auto-update 的 Ajax 怎麼可以這麼簡單(請用 thegiive 的口氣自行想像)。

*** 斜體字為你尚未命名或已經命名好的名稱 ***

[summary] 我們得準備:
  • 一個 controller 裡面的新的 action,假設該 action 名稱為 action-name,該 controller 名稱為 controller-name。
  • 一份 RJS template,置放在 /app/views/controller-name/action-name.rjs。
  • 一份 partial template,假設置放在 /app/views/controller-name/_show_topics.rhtml。
  • 在適當的地方加入 javascript。


step 0:
首先在預設的 layout 中掛入 prototype 等 JavaScript。寫法如下:

<%= javascript_include_tag :defaults %>

其中 :defaults 會將 /public/javascripts/ 中預設的 JavaScript 都掛載上來。如果不想全部掛上來的話,可以改寫成 :script-name。

step 1:
接著在你的 controller 裡面寫入一個新的 action。假設我們想要每分鐘更新文章列表:

def update_topics
# 取出最新的 forum 文章,get_all_topics 請自己在 model / controller 撰寫
@all_topics = get_all_topics(10) # hard code 是不好的,小朋友不要學。也可以順便做錯誤處理。
end

step 2:
接著是你必須建立一個檔案 /app/views/controller-name/action-name.rjs,在這個 RJS template 裡面使用 prototype helper 裡面的 methods 來與瀏覽器溝通。內容如下:

page.replace_html 'update-topics-div', :partial => 'show_topics', :object => @all_topics
page.visual_effect :highlight, "update-topics-div"

我們用了 replace.html 來幫我們做取代的動作,如果是 digg-spy-style 的話,通常我們會用 insert.html,有空再來寫。值得注意的是,在這個檔案裡面無須使用 <%%> 來內嵌,直接撰寫即可。update-topics-div 這邊代表的是欲取代的 html element id,show_topics 則是欲取代的 partial template(注意 template 的命名有 prefix _,render 時無須 prefix _,也無須副檔名),再利用 :object 將變數 binding 到 template。visual_effect 效果我就不介紹了。

step 3:
當然你要有輸出的 view,我們假設是 /app/views/controller-name/another-action-name.rhtml。部份的片段應該有:

...
<%= render :partial => 'show_topics' %>
...

而我們的 template _show_topics.rhtml 假設長成這個樣子:

<div id='update-topics-div'>
<ul>
<% @all_topics.each{ |topic| %>
<li><%= topic.title %></li>
<% } %>
</ul>
</div>

step 4:
最後我們挑選一個適當的地方加入 JavaScript,什麼叫適當的地方呢?因為有些 template 會共用的關係,如果把 JavaScript 加入到共用的 template,會出現 RJS 找不到 html element id 的錯誤,所以說得擺在適當的地方,當然跟瀏覽器的支援程度也有關係。假設找到了適當的地方,則我們加入 JavaScript 如下所示:

var updateInterval = 60 * 1000; // 每分鐘 update 一次
var timer;

function goUpdateTopics() {
timer = setInterval('updateTopics()', updateTopicsInterval);
}

function updateTopics() {
// url 記得寫對!
url = "/controller-name/action-name";
new Ajax.Request(url, {
asynchronous: true,
method: "get",
});
}
goUpdateTopics();


Well, 經過這四步驟,你應該已經可以快樂地使用 Ajax 整合在 Rails 裡所提供的功能與樂趣。:)

延伸閱讀

3/11/2007

Rails 當中使用 Google Map:YM4R


最近發現 Google Map 很好玩,想要玩玩 Ruby on Rails 上面的 Google Map,就找上了 YM4R 這個 Rails Plugin,發現 YM4R 使用 Google Map真是方便呀,彈指之間搞定。YM4R 這個 Plugin 就是讓Ruby on Rails 上面使用 Yahoo Map 跟 Google Map 的 Rails Plugin。以下介紹一下這個 YM4R 怎麼使用。


安裝:

ruby script/plugin install svn://rubyforge.org/var/svn/ym4r/Plugins/GM/trunk/ym4r_gm


這個動作會把相關的 file copy 到 config,vendor/plugins, public/javascripts 裡面去,如此就把這個 YM4Rplugin 裝完了。

使用:
要使用這個 plugin 一共分成 controller 跟 view 兩個部份。

Controller:

在 controller 裡面加入底下的 code ,底下的 code 是改自這個網頁,他會 initial 一個 Gmap Object,顯示我們指定的位址。我們這裡舉台北為例子,台北的經緯度根據 Wikipedia ,為東經121.6度,北緯24.9度,放大的程度為 7,並且有一個 info_windows。
latitude = '24.9'
longitude = '121.6'
@map = GMap.new("map_div_id")
@map.control_init(:large_map => true, :map_type => true)
@map.center_zoom_init([latitude,longitude], 7)

marker = GMarker.new([latitude, longitude],
:title => "台北", :info_window => "我在台北呦~")
@map.overlay_init(marker)

View :

Google Map 使用方式都是 Javascript。要在 Ruby on Rails View 裡面使用方式,分成兩個步驟,第一個是在 head 裡面加入相關的 Javascript
<%= GMap.header %>

第二個就是在 Body 裡面,顯示剛剛在 controller 裡面設定完成的 @map 變數,這裡寬跟高都設定 600
<%= @map.to_html %>
<%= @map.div(:width => 600, :height => 600) %>


啟動:

請打入 http://localhost:3000/controller_name/ 就可以看到台北的 Google Map 了

等等,我都沒看到 Google API Key ?

是的,我們上面的例子都不用設定 Google API Key 的原因,是因為我們使用的 Domain 是 http://localhost:3000/ ,而這個 Plugin 已經預設裝入 http://localhost:3000/ 的 Google API Key 。

如果你想設定你的 Domain ,請到 config/gmaps_api_key.yml 裡面設定,請將你申請的 Google API Key ,放入 production 設定底下。話說,我不知道為啥我明明跑的是 development mode,但是將申請好的 API Key 放在 development 底下他不 work,反正似乎只能放在 production mode 才可以 work。

延伸閱讀:
  1. Rails Google Maps Plugin 教學
  2. YM4R Project Hompage

2/09/2007

In-plcae-editing by Rails


ㄜ,其實真的很難解釋什麼叫做 in-place-editing 這個 AJAX 效果,簡單講就是你可以直接編輯畫面上某些欄位,而不用進入專門編輯的頁面,上圖就是最典型的效果。

這個效果廣泛的使用在 Flickr 以及其他的 AJAX 網頁。由於太過方便,常用,所以 script.aculo.us 就有這個效果,Rails 也對這個效果寫了相當方便的 Javascript Helper,並且做出一個相當完善的整合。雖然這個功能在 Rails 2.0 裡面即將被取消內建,轉為 plugin 形式,但是由於日常生活使用到的機會也蠻多的,我還是第一個 AJAX 效果就介紹這個。Ruby on Rails 上面要使用 in-place-editing 是相當相當方便的。一共有三步,我們假設我們想 in-place-editing abc model 裡面的 name column。

第一步:加入相關 Lib
在 HTML head 裡面加入相關 Javascritp Lib
javascript_include_tag :defaults


第二步:View
在view 裡面,你需要 in-place-editing的位置,加入相關 in-place-editor 的 field
in_place_editor_field 'abc' , 'name'


第三步:Controller
在你的 controller 裡面,加入 in-place-editor 的宣告
class AbcController < ApplicationController
in_place_edit_for :abc , :name
end


沒錯,不多不少三步就好。沒有任何 Javascript 宣告,只有簡潔有力的 Rails Style Coding,很棒吧。

中文化

如果你想將裡面內建的 ok , cancel 改成中文的話,請在 view 裡面使用
in_place_editor_field 'abc' , 'name' , {} , :save_text => '儲存' , :cancel_text => '取消' , :loading_text => '儲存中'
即可變成中文字。

多個 column in-place-editing

如果你想要一個 controller 有多個 in-place-editing 的 column,這裡就有點不方便了,可能必須要這樣寫
class AbcController < ApplicationController
in_place_edit_for :abc , :name
in_place_edit_for :abc , :nickname
end

延伸閱讀