iT邦幫忙

3

[NodeJS] 第一次 NodeJS 就上手 Part 2

接著上次的 Part 1 這回繼續寫樣板與資料庫的部份。
使用樣板

每次都要寫一大堆 .html 檔案,當你的檔案越來越多的時候,改起來就相對麻煩。而且,我們也想把一些變數傳進去用,這個時候樣板引擎就是個解決方法。Express 所支援的樣板引擎相當多元,

Haml
Jade
EJS
CoffeeKup
jQuery Templates

這裡有剛剛提到的 EJS 跟 Jade,而其實我現在慢慢地再改用 CoffeeKup,所以,這裡我挑了 Jade 來作一些簡單介紹。喔,為什麼不是介紹 CoffeeKup?因為這樣我還要再講一次 CoffeeScript,所以我還是講 Jade 就好了(飄走

我們在 Express 要怎麼使用他呢?請看底下簡單範例,

var express = require("express"),
app = express.createServer(express.logger());

app.configure(function() {
    app.set("views", __dirname + "/views");
    app.set("view engine", "jade");
});

app.get("/", function(req, res) {
    res.sendfile(__dirname + '/index.html', function(err) {
        if (err) res.send(404);
    });
});

app.get(/(.*)\.(jpg|gif|png|ico|css|js|txt)/i, function(req, res) {
    res.sendfile(__dirname + "/" + req.params[0] + "." + req.params[1], function(err) {
        if (err) res.send(404);
    });
});

port = process.env.PORT || 3000;
app.listen(port, function() {
    console.log("Listening on " + port);
});

我們將 View 的資料夾設定在 views 底下,然後將樣板引擎指定為 jade,這樣,我們就可以開始寫一個 index.jade 這樣的樣板檔案了。請記得,檔案是放在 views 資料夾下面的,

h1 "Hello NodeJS"

這樣就可以了嗎?當然不是,我們還要修改一下 web.js 才行,

var express = require("express"),
app = express.createServer(express.logger());

app.configure(function() {
    app.set("views", __dirname + "/views");
    app.set("view engine", "jade");
});

app.get("/", function(req, res) {
    res.render("index", {layout: false});
});

app.get(/(.*)\.(jpg|gif|png|ico|css|js|txt)/i, function(req, res) {
    res.sendfile(__dirname + "/" + req.params[0] + "." + req.params[1], function(err) {
        if (err) res.send(404);
    });
});

port = process.env.PORT || 3000;
app.listen(port, function() {
    console.log("Listening on " + port);
});

這樣就可以運行了,使用樣板的好處是,你不用一直重新啟動 node 的服務,只要改了樣板內容,他就會做改變。並不會因為他是樣板引擎而需要重新啟動 node 的服務。那,我要怎麼傳變數進去呢?請看,

app.get("/", function(req, res) {
    res.render("index", {
        layout: false,
        nickname: "閃光洽"
    });
});

樣板要怎麼接收呢?

h1= nickname

關於 Jade 還有相當多的變化可用,在他的 gitHub 說明中寫得還算詳盡,包含了陣列、邏輯判斷、字串處理等等。想要知道更多詳細操作的人,可以去他們的 gitHub 看看。

WebSocket

因為新的瀏覽器開始實做 websocket 的部份(我沒有說 IE),所以 NodeJS 在一開始就對這一塊有部份的支援,不過因為當初改版頻繁,所以有些東西其實寫完之後,改版就爛掉的事情時常發生,也被人詬病。

BUT!

救星出現了,他叫做 socket.io,你應該很好奇他要做什麼?舉個簡單的例子,聊天室那麼多人一來一往,訊息即時性的發佈與傳遞,就可以靠他來完成。其實 NodeJS 本身就有這種機制,只是當初並不完善,而有這些模組的助力,讓這些事情變簡單而已。

當然是要安裝的,

$ npm install socket.io

然後就請看官方的範例(喂,其實我說正格的,官方的範例相當完整。這個模組其實只是替我們做掉了 NodeJS 關於 Event 這個部份而已,他並沒有很囉唆的做很多事情。

而且他的好處是,我也可以拿去給前端用,就此,聊天室一來一往的傳送就可以串起來了。當然,WebSocket 可以做的事情不只聊天室,只是舉這個例子比較容易理解而已。所以我貼一下官方範例,應該不過份吧 XD

var express = require("express"),
app = express.createServer(express.logger()),

io = require("socket.io").listen(app);

app.configure(function() {
    app.set("views", __dirname + "/views");
    app.set("view engine", "jade");
});

app.get("/", function(req, res) {
    res.render("index", {layout: false});
});

app.get(/(.*)\.(jpg|gif|png|ico|css|js|txt)/i, function(req, res) {
    res.sendfile(__dirname + "/" + req.params[0] + "." + req.params[1], function(err) {
        if (err) res.send(404);
    });
});

io.sockets.on("connection", function (socket) {
    socket.emit("front-end", { hello: "world" });
    socket.on("my other event", function (data) {
        console.log(data);
    });
});

port = process.env.PORT || 3000;
app.listen(port, function() {
    console.log("Listening on " + port);
});

我們的 index.jade 也要改一下,

!!! 5
html
  head
    meta(charset="utf-8")
    title "Hello Socket.IO"
    script(src="/socket.io/socket.io.js")
  body
    h1= nickname
    script
      var socket = io.connect();
      socket.on("front-end", function (data) {
          console.log(data);
          socket.emit("my other event", {my: data});
      });

這個 index.jade 也改太多了吧,其實我就只是把他寫得比較規矩一點而已,沒有改很多啦。這個範例做了兩件事,

主機監聽了一個叫做 my other event 事件。
當連入 / 的時候,主機觸發了 front-end 這個事件。
用戶端監聽了一個叫做 front-end 事件。
當該事件觸發時,會再觸發 my other event 這個事件。
這樣知道他們兩個人之間發生什麼事情了嗎?其實就像是打來打去鬧來鬧去戳來戳去的小情侶而已嘛。

關於資料庫

當然是用目前最熱門的 Mongo 資料庫,其實你要用 MySQL 也不是不行,

Node - MongoDB
Node - MySQL

不過這裡以 MongoDB 為例子,當然,你的系統需要安裝 MongoDB,才能用囉!

$ npm install mongodb

應用程式的部份稍做修改,

var express = require("express"),
app = express.createServer(express.logger()),

io = require("socket.io").listen(app),

mongodb = require("mongodb"),
mongodbServer = new mongodb.Server("localhost", 27017, {
    auto_reconnect: true,
    poolSize: 10
}),

db = new mongodb.Db("mydatabase", mongodbServer);


app.configure(function() {
    app.set("views", __dirname + "/views");
    app.set("view engine", "jade");
});

app.get("/", function(req, res) {
    res.render("index", {layout: false});
});

app.get(/(.*)\.(jpg|gif|png|ico|css|js|txt)/i, function(req, res) {
    res.sendfile(__dirname + "/" + req.params[0] + "." + req.params[1], function(err) {
        if (err) res.send(404);
    });
});

io.sockets.on("connection", function (socket) {
    socket.emit("front-end", { hello: "world" });
    socket.on("my other event", function (data) {
        console.log(data);

        db.open(function() {
            db.collection("test", function(error, collection) {
                collection.insert({
                    data: data
                });
                db.close();
            });
        });
    });
});

port = process.env.PORT || 3000;
app.listen(port, function() {
    console.log("Listening on " + port);
});

以上的例子,是當用戶端觸發了 my other event 的時候,會將用戶傳來的 data 儲存在 mydatabase 這個資料庫中,且儲存的集合是 test,欄位的名稱叫做 data。

當然,例子太簡單就不好玩了,這裡面有一個 Bug。

這裡有一篇關於 NodeJS 與 MongoDB 的文章,可以參考:
NodeJS 與 MongoDB 的邂逅

小結

NodeJS 對這個世界的衝擊當然不只如此而已,Javascript 變成顯學這件事情可能也是始料未及。不過,這些事情總是會讓人興奮的,就端看未來會如何去發展了!

結果到最後我真的沒提到 CoffeeScript


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言