Zeta.js之工廠方法

前言

Zeta.js 是一款爲node打造的輕量級後端框架,引入了許多angular的概念,可讓你以一種不一樣於express的更有層次的方式編寫後端代碼。這裏是Zeta的中文文檔。node

Source On GitHubgit

Website For Zetagithub

概覽

從某種程度上來講,工廠完成了和Provider類似的工做,但區分於後者的是對於每一個新請求工廠都會提供一個新對象而非共享同一個對象。另外,工廠也必須是一個一個返回對象的函數而非對象自己。在許多情形下,你能夠任意選用這兩種完成任務,但確實還有一些狀況引入工廠會更方便合理。express

開始

定義工廠

同Provider同樣,工廠是由module註冊的,例子以下。後端

jsdemo.factory('$sayhi',function(){
    return {content:'hi,world'};
});
//demo is a module

如今,你獲得了一個名叫$sayhi的返回一個帶有值爲‘hi,world’的屬性content的對象的工廠,字母「$」 並不是必要的,但咱們推薦你把它放在你所選定的工廠名字的開頭以將工廠與普通的變量區分開來。cookie

工廠能返回你要的任何東西,包括函數。框架

jsdemo.factory('$plus',function(){
    return function(a,b){
        return a+b;
    };
});

而且你能夠在工廠中使用$scope,只要把它加到函數參數列表裏。關於$scope的詳細事宜,你能夠在接下來的章節裏看到。ide

使用工廠

如同Provider,工廠也是被設計用在請求處理函數裏的。函數

js//$plus is defined in the example before
demo.get('/',function($scope,$plus){
    $scope.send($plus(1,2).toString()).end();
});
//the client will get '3'

咱們所使用的$plus 函數並不是所定義的工廠自己而是工廠所返回的對象,同時不要忘了將工廠名追加到請求處理函數的參數列表裏。post

取出工廠

就像Provider同樣,已經定義過 的工廠也能夠被取到。

jsvar plus=demo.factory('$plus')();
console.log(plus(1,2));
//3 will be got
var dus=demo.factory('$wel');
dus==undefined//true

簡單的例子

下面是一個稍微複雜的例子,照例忽略您閱讀到的不能理解的地方。

js//main.js file
var zeta=require('zeta');
var demo=zeta.module('demo',['demoFactory']);
demo.load();
demo.get('/',function($scope,$plus){
   $scope.send($plus(1,2).toString());
});
js//Factory.js
var zeta=require('zeta');
var demoFactory=zeta.module('demoFactory',[]);
demoFactory.provider('$plus',function(){
    return function(a,b){return a+b;};
});

工廠的繼承也是由module的依賴注入實現的。

工廠進階

工廠使用Provider

使用Provider毫無困難,將Provider的名字加到定義的工廠函數的參數列表裏便可。

jsdemo.provider('$wel',{
    a:1,
    b:2,
    c:3
});
demo.factory('$sum',function($wel){
    var sum=0;
    for(var i in $wel){sum+=$wel[i];}
    return sum;
});

工廠使用工廠

同上面類似,同樣用例子說明吧。

jsdemo.factory('$wel',function(){
    return {
        a:1,
        b:2
    };
});
demo.factory('$sum',function($wel){
    return function(){
        var tmp=$wel();
        return tmp.a+tmp.b;
    };
});

工廠的意義

既然已經有了Provider,你可能會問爲何還要引入工廠的概念。首先讓咱們考慮對於處理表單提交的兩種實現方式。

js//Use Provider
var formidable=require('formidable');
demo.provider('$form',formidable);
demo.post('/upload',function($scope,$form){
    var tmp=new $form.IncomingForm();
    tmp.on('file',function(file){...});
});
js//Use Factory
var formidable=require('formidable');
demo.factory('$form',function(){
    return new formidable.IncomingForm();
});
demo.post('/upload',function($scope,$form){
    $form.on('file',function(file){...});
});

經過上面的例子,你應該已經很是清楚二者之間的區別,而上文的服務並未對兩種方式顯示出偏心,但考慮一下處理cookie的情形。若是咱們要用一個對象表示每一個請求附帶的cookie,因爲每次請求cookie都不一致,而把parse的過程留到handler裏顯然不那麼美,有了工廠,這就不足爲慮了。

jsdemo.factory('$cookie',function($scope){
    var cook={};
    cook._val=parse($scope.req.headers['cookie']);
    cook._option={};
    cook.getValue=function(name,optName){...};
    cook.setCookie=function(obj){..};
    ...
});

能夠看出來,對於cookie這類每次請求都須要一個全新的對象的狀況,工廠是一個更明智的選擇。

注意事項

  • 工廠能夠經過重定義覆蓋。
jsdemo.factory('$compute',function(){
    return function(a,b){return a+b;};
});
demo.factory('$compute')()(1,2)==3//true
demo.factory('$compute',function(){
    return function(a,b){return b-a;};
});
demo.factory('$compute')()(1,2)==1//true
  • 不要忘了在請求處理函數的參數列表加入工廠名。
  • 工廠必須是一個函數,其參數能夠包含其所依賴的。而且你在請求處理函數中用到的是工廠所返回的而非其自己。
  • 同一個請求的多個處理函數共享同一個工廠返回的對象
jsdemo.factory('$count',function(){
    return {num:0};
});
demo.handler('h0',function($scope,$count){
    $count.num++;
    $scope.go('next');
});
demo.handler('h1',function($scope,$count){
    $scope.send($count.num.toString()).end();
});
demo.get('/',['h0','h1']);
//the client will get 1 instead of 0
  • 對於每一個新到來的請求工廠返回新的對象
jsdemo.factory('$count',function(){
    return {num:0};
});
demo.get('/',function($scope,$count){
    $scope.send($count.num.toString());
    $count.num++;
    $scope.end();
});
//the client will get 0 every time requesting path '/'
相關文章
相關標籤/搜索