iT邦幫忙

DAY 25
4

node.js伺服器實戰系列 第 25

node.js伺服器實戰(25) - 初步設計視圖與模型的互動方式

在MVC中,三種物件如何互動,是設計的關鍵。基本上目前Controler已經確定了,所以還需要決定View與Model的互動方式。
構想

由於Model可能是MVC三者之中最花時間的,比較好的策略是,先由Model準備好資料,當資料準備好,再呼叫View來呈現。

另外,為了簡化設計,盡量要讓Model與View是一對一的關係,所以傳遞的資料必須匹配:
* View要能直接剖析Model傳過來的資料,並且把它render出來(透過template)
* 從另外一方面來說,Model準備丟給View的資料,必須是View可以處理的

在介面上,目前想到的做法是:
* View與Model都做成獨立的module
* 利用Model的constructor傳入對應的View的instance
* 利用View的constructor,把伺服器實際進行render用的callback傳給它
* 呼叫Model的execute方法,Model會進行查詢,並且準備好要傳遞給View的資料物件
* Model的execute方法會呼叫View的render方法,並且把資料物件傳給它產出呈現的結果

概念性實做

models.js的概念性實做:

 module.exports = {
     hello: function(view) {
         var data = {
             name: 'fillano'
         };
         this.execute = function() {
             process.nextTick(function() {
                 view.render(data);
             });
         }
     }
 };

裡面只是提供一個簡單的stub資料,然後與view互動。

views.js的概念性實做:

 var hello = 'Hello: {%$name%}';
 
 var varParser = function(str, obj) {
     for (var i in obj) {
         if (obj.hasOwnProperty(i)) {
             var tmp = new RegExp('\\{%[ ]*\\$'+i+'[ ]*%\\}', 'g');
             str = str.replace(tmp, obj[i]);
         }
     }
     return str;
 }
 
 module.exports = {
     hello: function(cb) {
         this.render = function(obj) {
             cb(false, '/hello_mvc', {type: 'text/html', data: varParser(hello, obj)});
         };
     }
 };

目前還不實際讀取template檔案,而是先用簡單的stub來代替。html模板的內容放在hello變數中,varParser會從傳入的物件中,把對應的資料放入hello變數中的html模板,產出要呈現的資料,然後呼叫伺服器負責render的callback,把頁面輸出。

然後在整合測試中新增一個測試,首先修改setUp,加入一個router:

        .get('/hello_mvc', function (request, response, cb) {
            var HelloModel = require('../lib-cov/models').hello;
            var HelloView = require('../lib-cov/views').hello;
            var m = new HelloModel(new HelloView(cb));
            m.execute();
        });

然後增加一個叫做"test router hello_mvc"的測試:

    "test router hello_mvc": function(test) {
        test.expect(3);
        var req = this.http.request({
            "host": "localhost",
            "port": 8443,
            "path": "/hello_mvc",
            "method": "GET"
        }, function(response) {
            var result = [];
            response.on('data', function(data) {
                result.push(data);
            });
            response.on('end', function() {
                var total = 0;
                var entity = '';
                for(var i=0; i<result.length; i++) {
                   total += result[i].length;
                   entity += result[i].toString('utf8');
                }
                test.equal(200, response.statusCode);
                test.ok(entity.indexOf('Hello')>-1);
                test.ok(entity.indexOf('fillano')>-1);
                test.done();
            });
        });
        req.end();
    }

跑過整合測試,看起來這樣的設計有達到設計的目標。

今天的範例檔fillano-evolve-v0.0.18-0-g4d4f485.zip,目前版本是v0.0.18。

相關文章


上一篇
node.js伺服器實戰(24) - 開始設計視圖機制
下一篇
node.js伺服器實戰(26) - 整合模板引擎
系列文
node.js伺服器實戰33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言