2012年10月26日 星期五

[宅] 菜鳥出槌筆記 - 本地化設置錯誤

今天要執行mongo指令時,一直出現以下錯誤訊息:

terminate called after throwing an instance of 'std::runtime_error'

  what():  locale::facet::_S_create_c_locale name not valid

Aborted (core dumped)

上網查了一下發現是本地設定的問題,所以在mongo指令之前加上"LC_ALL=C"就可以成功執行了
LC_ALL=C mongo

[宅] node.js開發筆記(2) - 以express-vhost來建立虛擬主機 & 背景執行node.js

為了在同一個主機上搭載不同網域的網站,在npm上survey了一下相關套件,最後找到了express-vhost:
npm install express-vhost
express-vhost是express的middle-ware,可以透過resiter將特定的網域綁定指定function,來達到以網域做分流的功能。詳情請看:https://github.com/vast-eng/express-vhost

我們希望node能夠在背景執行,而且即使登出主機也能繼續提供服務。
這時我們就要使用forever,他能夠讓你的js檔在背景執行,以下是安裝及啟動方法:
npm install -g forever//記得要設定為全域
sudo forever start server.js//若要以80port開啟服務,記得要以root權限執行

比較要注意的是,利用forever來執行js檔是沒辦法讓你看到console.log的,所以在啟動之前最好用node指令執行一次,確定服務正常再使用forever來開啟sever。尤其是你的server預設listen 80port時,忘了加sudo又沒有相關提示可能會讓你白白debug老半天還找不出原因。

話說其實node最好不要listen 80port,而是用其他伺服器程式來轉接給他,詳細原因可能下一篇再解釋。

2012年10月25日 星期四

[宅] node.js開發筆記(1) - 從安裝到express

最近開始使用node來開發一個vhost 應用~
因為之前是玩的時候是使用windows的環境,這次改在Ubuntu上開發,重新安裝的過程中也順便以筆記整理一下。

<step1> 安裝相關需求
因為這個環境空空如也,非常的乾淨,所以事先必須把一些基本的需求給建立起來
sudo apt-get install python-software-properties
sudo apt-get install make
sudo apt-get install g++
sudo apt-get install git
以上都搞定後就可以從github上下載下來並安裝了:
git clone https://github.com/joyent/node.git
cd node
git checkout v0.6.7
./configure
make
sudo make install
這樣就裝好了~

<step2>安裝npm
npm之於node就好比gem之於ROR,
gem之於ROR就好比apt-get之於Ubuntu....科科

咳,總之npm是node的套件安裝工具,
比較常用到的指令不外乎
npm install -g {你要裝的套件} //-g是代表這個套件可被全域使用,可以不用加
npm search {你要查的關鍵字}
npm list //列出你已安裝的套件

在安裝套件後,npm會把套件的module放在當下資料夾的"node_modules"資料夾中,
在執行node時就可以require該module,前提是執行的js檔所在的資料夾下要有"node_modules"資料夾且裡面那些module才行。
不過照理來說,我安裝的全域套件不用特別塞在裡面就找得到了,事實證明是不行啊~Orz
鳩竟是怎麼回事還得再查查~

<step3>用npm安裝express
express必裝!!!怎麼裝請看下面:
sudo npm install -g express
當要全域安裝時記得加sudo,不然會失敗

<step4>啟動server
我們要使用express的API來設定特定routing的response,將以下程式碼寫入"server.js":
// create server.
    var express = require('express'),
        app = express(),
        port = 1337; 

    app.listen(port);

    // normal style
    app.get('/', function(req, res){
        res.send('hello world');
    });
執行:
node server.js

就可以在localhost:1337上看到"hello world",代表server正常的運行囉~


2012年10月10日 星期三

[宅] coffeescript第一課 - "原來不能這樣寫"

為了開發node以及導入同伴的python開發經驗,從今天開始接觸coffeesscript,來體驗他簡短程式碼並最佳化成javascript的能力。

一開始當然是要體驗一下他和javascript的不同啦,
首先是scope的習慣,在javascript中我們會習慣用大括號來圈起範圍,而在coffeescipt中我們使用縮排。
再來,在javascript中很常見的 for( i in obj)在coffeescript中是會有問題的,因為他會把這段程式轉化為:

for (_i = 0, _len = obj.length; _i < _len; _i++) {
}

而object預設根本沒有length,而這段程式碼很明顯就是為了array寫的,運用在array上當然也沒問題。那要loop物件中的attr該怎麼辦呢?我們只需要改成 for( i of obj)即可,而因為coffeescript具有List comprehension的特性,讓他能用以 下的方式來寫loop:

alert item for item of v

而不用

for( item of v){
     alert(v[item])
}

超快的,對吧?

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