2012年9月28日 星期五

[宅] html5筆記 - Local Storage


最近用Local Storage的html5當成一個類似client端的DB來做一點小應用
當中發現了一點小心得,在此紀錄一下:

localStorage是html5規格下,直接存在於window物件底下的Object,他的腳色跟cookie有點像,但是容量比較大,也不用每次都傳回給server。
美中不足的是,你要存入的資料都必須以string的形式做儲存
localStorage.test={};//這樣應該是Object吧
typeof(localStorage.test);//結果是String....Orz
所以在使用他的時候我們就要稍微用一點心思了,而JSON的.stringify()以及.parse()正好適合處理這樣的問題!

首先,我們在localStorage中建立一個名為test的property:
localStorage.test="{}";
為什麼要刻意在字串中加入上下括號呢?這是因為雖然我們只能以字串方式存入localStorage,但是可以寫成json的格式,再以JSON.parse()將他轉成真正的物件,讀寫完畢後再以JSON.stringify()轉成字串,存回去就好了。

[宅] javascript筆記(7) - javascriptMVC-Model

最近因為工作的關係開始接觸javascriptMVC,雖然網路上的評價不像Ember那麼的好,也沒有所謂的UI-binding,但是開發團隊很用心的寫了fixture、document等好用的功能,甚至支援command line產出程式碼,一開始用起來的感覺很像是client端的ROR~
至於這些功能有沒有在Ember上被實現我就不知道了,或許有機會可以試試看。

Model:

稍微接觸過MVC架構的朋友應該就知道,Model是負責跟資料庫溝通的部分。
在client端的MVC架構雖然無法直接存取資料庫,但在javascriptMVC中內建了restful的方法,可以經由save(對應update), find(對應select), findAll(select all)等method來呼叫定義的restful:
$.Model('Todo',{
    findAll: 'GET /todos.json',
    findOne: 'GET /todos/{id}.json',
    create:  'POST /todos.json',
    update:  'PUT /todos/{id}.json',
    destroy: 'DELETE /todos/{id}.json'
},{});
這樣就產生了一個Todo的class,而他有著這些restful路徑,我們可以利用Todo來新增一些instance如下:
var todo = new Todo();
這時你可能會想問,那我要怎麼寫入可以被所有instance共同繼承的property呢?
在一開始創建Todo這個class時,我們可以在第三個parameter(型別為Object)內寫入我們要預設的property,就是我標示為紅色的地方啦~

所以假設我在一開始建立Todo這個Model時希望他的instance都能有一個叫做"spotlight"的function以及priority的屬性,我們就要改寫成這樣:

$.Model('Todo',{
    findAll: 'GET /todos.json',
    findOne: 'GET /todos/{id}.json',
    create:  'POST /todos.json',
    update:  'PUT /todos/{id}.json',
    destroy: 'DELETE /todos/{id}.json'
},{
    spotlight : function(){},
    priority : 0
}
);
如此一來被建立出來的todo instance應該會有如下的properties:

priority(number) spotlight(function) constructor(function) Class(function) setup(function) update(function) errors(function) attr(function) bind(function) unbind(function) _updateProperty(function) removeAttr(function) attrs(function) serialize(function) isNew(function) save(function) destroy(function) identity(function) elements(function) hookup(function) created(function) updated(function) destroyed(function) proxy(function) callback(function)

其中save這個function就是對自己這個instance做update的工作,但這時候你可能會發現一但我真的執行了save這個method,傳出的data中卻空空如也,這是因為你不是透過建構子或是.attr( )來對這個instance建立property的!不然總不能要這個instance傻傻地將以上一長串properties全部update上去吧?
為了要讓這個instance知道哪些是自己應該要儲存的attributes,我們可以在建立instance時加上建構子的參數,如下:
var todo = new Todo( {'priority' : 0, 'spotlight' : function(){}} );
或是在創建之後用.attr( )來加入attributes:
todo.attr('priority',0);
這時你可能會想問:「那這個instance是怎麼記錄這些attribute是要被上傳的呢?」
你會發現在這個instance中有一個叫attrs的function,呼叫他之後會返回一個Object,裡面有你到目前為止所增加的attributes,也就是save時所上傳的data!

所以這代表每次每次我們要修改attributes都得透過attr嗎?
答案是不必的~透過建構子或是.attr( )來建立attriutes只是順便做一個類似"註冊"的動作,之後即使是直接進行如下的操作,呼叫attrs後也可以發現數值真的有被修改到:
todo.priorirt=1;
暫時先這樣。

2012年9月24日 星期一

[宅] javascript筆記(6) - jQuery plugin

在使用jqgrid時一定常看到這種用法:
$("#grid").jqgrid(.....);

這種對jQuery元素做操作的method就是利用extend把它綁在上面的,而extend又分兩種用法:
jQuery.extend
jQuery.fn.extend

第一種jQuery.extend可以看作是直接在jQuery上加入一個方法,舉個網路上找到的例子:

 <script type="text/javascript">
        jQuery.extend({
            add: function(a, b) {
                return a + b;
            }
        });
        alert($.add(3, 4)); //7
 </script>
這樣的功能可以直接用"$.定義的function"來執行。

第二種jQuery.fn.extend只能用在jQuery元素上,jqgrid用的就是這種方法了,當要對元素做操作時只要用this即可:

 <script type="text/javascript">
        jQuery.fn.extend({
            red: function() {
                return $(this).css('color', '#ff0000');
            }
        });
        $('#test').red();
</script>

在網路上查了一下也有發現不用extend來做plugin的:

$.fn.hilight = function() {
  // Our plugin implementation code goes here.
};
但這之間有什麼差異就還要再做研究了~

更詳細一點的介紹與範例可以看:ericsk.net-擴充 jQuery


2012年9月14日 星期五

[宅] ROR筆記(1) - "ActiveRecord::ConnectionNotEstablished"問題

因為考慮到後期的延伸以及功能性,我捨棄了預設與ROR綁定的sqlite,改用postgresql來做為網站的資料庫,在設定好database.yml後,在routing時卻發生了ActiveRecord::ConnectionNotEstablished的錯誤訊息。上網survey一下才發現原來是資料庫的相關設定不夠完全,所以整理了一下設定資料庫所必需的步驟:
(單純只是個page reguest也要過sql那一關...是要整誰...Orz)

1. database.yml : 

在這個檔案中你可能會看到三個設定分別是development, test, production,分別是在開發、測試、正式上線時所用的三種模式,基本上應該是要長這樣:

development:
  adapter: postgresql
  database:[給ROR使用的資料庫]
  pool: 5
  timeout: 5000
  username: [給ROR使用的帳號,必須有全域的CREAT權限]
  password: [密碼]
  host: [你的database路徑]
尤其是最後一句特別要注意,因為預設使用的sqlite是不用安裝且在本機端運行的database,所以在原本的設定並沒有host這個項目,要自己加上去。
以上是以development mode為例,其他的mode也是差不多的概念。

2. gemfile:

這個檔案可以在專案的根目錄裡找到,其中有一行會是 : gem 'sqlite3'
這是提示系統說我們需要用到sqlite的gem,在這邊請改成" gem 'pg' "

3. 安裝gem pg:

在gemfile中做了使用postgres的設定卻沒安裝postgres的gem是跑不起來的,這時請在commend line中打"gem install pg"就會安裝好了。
貓桑一開始安裝成gem install postgres也是成功的,但卻發現那是比較舊的postgres driver,在2008年後就不被支援了,當然也跑不起來。

2012年9月11日 星期二

[宅] javascript筆記(5) - 關於z-index、visibility和滑鼠點擊事件


好吧,我承認這篇的主題很亂...


z-index、visibility


首先,z-index的概念很簡單,只要他的值越大代表離你越近,也就是越上層。
visibility則是可以設定成"hidden"或"visible"。

這兩個css屬性是我今天在寫一個light-box的時候所用到的,程式碼如下:

<div id="sb-container" style="visibility: hidden;">
</div>
<div onclick="$('#sb-container').css('visibility','hidden')" style="background-color: black; height: 100%; left: 0px; opacity: 0.8; position: fixed; top: 0px; width: 100%; z-index: 9;">
</div>
<br />
<div id="info-box" style="background-color: white; height: 440px; position: fixed; top: 100px; width: 540px; z-index: 10;">


最外層的"sb-container"是把裡面的兩個div裝起來的這不用多說,裡面的第一個div經由以上的設定後會向一層半透明(opacity:0.8)的遮罩蓋住整個可視範圍。

而在剛創建這個物件時發現有些網頁物件的層級比他稍高,所以我增加了z-index的屬性並設定為比較高的數字(9),這層遮罩就蓋住了整個頁面。

在遮罩之上還要有一個類似dialog的視窗來顯示內容,而他勢必要比遮罩還上面一層,否則會被遮掉,這裡可以看到他的z-index為10。

我想讓這個功能跟facebook顯示圖片的方式一樣,點選黑黑的地方就可以把這個 light  box關掉,所以大家可以看到在遮罩的部分有個$("#sb-container").css("visibility","hidden")的onclick事件。

運用z-index和visibility就可以做出簡單的 light  box效果了。



要補充說明的是,在一般的佈版及配置下,即使visibility為hidden的物件還是會占空間的,若要在隱藏時不要占用空間,可用display:none;


滑鼠點擊事件


當滑鼠點下時,我們可從e中找到一個button屬性,內容可能是0~2其中一個,分別代表是哪個滑鼠按鍵被按下:
0 - 左鍵
1 - 中鍵
2 - 右鍵

2012年9月5日 星期三

[宅] javascript筆記(4) - jQuery selector


以對<table id="t">下所有<td>加掛click事件為例,多半會寫成: 
$("#t td").live("click", fn); 或 $("#t").delegate("td", "click", fn);

學習了學習了~感謝暗黑執行續大大
(http://blog.darkthread.net/post-2011-10-14-delegate-vs-live.aspx)