之前的開發比較匆忙,雖然有測試幫助驗證,但是還是需要詳細確認是否有符合需求,並且調整實做程式。
需求
其實需求很簡單,在使用route handler來開發伺服器程式時,伺服器會傳送一個callback,讓使用者把要呈現的畫面render出來:
.get('/hello', function (request, response, cb) {
cb(false, '/hello', {
type: 'text/html',
data: 'hello'
});
})
,而且這個callback需要能多次呼叫,分階段輸出。但是之前在這個callback中,直接觸發了post事件,導致它只能輸出一次,這樣會跟需求不符。所以需要調整。
另外,為了模組化的需求,盡量把這些功能拉到tools.js模組中,這個時候之前沒有分離好的變數就會作怪了。改起來很繁瑣,而且會牽動到每一隻程式,包括測試程式。
還有就是,伺服器使用的流程並不連貫,實體化之後,不能直接方法來加入host/route/fs mapping規則,要先呼叫host(),在一連串規則加入後,才能呼叫listen()。這樣用起來有點不順。
實做
之前的版本已經包裝了response物件,讓tools.serverRender callback輸出時,把資料放進output buffer,直到post dispatch時才把output buffer輸出到瀏覽器。但是callback沒寫好,所以無法多次呼叫。現在加入一個額外參數,決定是否要進入post dispatch。
這樣,在view裡面,就可以根據需求分次輸出:
"hello_mvc2": function(cb) {
var view = swig.compileFile('examples/temp3.html');
var header = swig.compileFile('tests/header.html');
var footer = swig.compileFile('tests/footer.html');
this.render = function(data) {
cb(false, '/hello_mvc2', {type:'text/html', data: header.render(data)});
cb(false, '/hello_mvc2', {type:'text/html', data: view.render(data)});
cb(false, '/hello_mvc2', {type:'text/html', data: footer.render(data)}, true);
};
}
最後一次輸出時,加上最後一個參數(true),就會把結果輸出到瀏覽器。
route handler的使用現在也可以比較連貫:
var Evolve = require('../lib/evolve');
var tools = require('../lib/tools');
var path = require('path');
var server = new Evolve({
dirindex: ['index.html', 'index.htm', 'default.htm']
})
.handle('pre', tools.cookieHandler)
.host('localhost:8443')
.map('/', path.join(__dirname, '../www'))
.get('/hello', function (request, response, cb) {
cb(false, '/hello', {
type: 'text/html',
data: 'hello'
}, true);
})
.get('/hello_mvc', function (request, response, cb) {
var HelloModel = require('./models')['hello_mvc'];
var HelloView = require('./views')['hello_mvc'];
var m = new HelloModel(new HelloView(cb));
m.execute();
})
.get('/hello_mvc1', function (request, response, cb) {
var HelloModel = require('./models')['hello_mvc1'];
var HelloView = require('./views')['hello_mvc1'];
var m = new HelloModel(new HelloView(cb));
m.execute();
})
.get('/hello_mvc2', function (request, response, cb) {
var HelloModel = require('./models')['hello_mvc2'];
var HelloView = require('./views')['hello_mvc2'];
var m = new HelloModel(new HelloView(cb));
m.execute();
})
.listen(8443, 'localhost');
還是需要先呼叫host()再加入route規則,但是可以一次串到底,這樣使用起來就更方便了。
今天的範例檔fillano-evolve-v0.0.21-0-g8637d69.zip,目前版本是v0.0.21。(這次修改的細節相當多,很難把變動的地方都貼上,建議可以用github的diff功能來看改了什麼。)