2014年7月16日 星期三

同步你的前端資料與後端資料 - 自建object filter

在Node.js/JavaScript中,因為弱型別加上沒有物件導向的概念
常常在開發NoSQL儲存的時候會有許多資料不一致的問題
下面是我常用的做法,給大家參考:

var _ = require('underscore'); 
//建立user model
var user = {
  username: {
    type: "string", require: true, max: 200
  },
  password: {
    type: "string", require: true, max: 200
  },
  nickname: {
    type: "string", require: false, max: 200
  },
  phone:{
    type: "string", require: true, max: 200
  },
  lang: {
    type: "string", require: true, max: 200, pick: ['cht', 'en']
  },
  mobile:{
    type: "string", require: true, max: 200,
    map: function(v) {
      return "886" + Number(v); //format number
    }
  }
}

//建立通用的filter function
function filter(vo, model) {
  var modelKeys = Object.keys(model);
  var out = {};
  for(var i = 0; i< modelKeys.length; i++) {
    var k = modelKeys[i];
    var v = model[k];
    //check required
    if(v.require)
      if(!vo[k]) throw "value of key [" + k + "] not found";
 
    //check vo has value
    if(Object.keys(vo).indexOf(k)>=0){
      out[k] = vo[k];
      if(v.type) {
        if(typeof(vo[k]) != v.type) throw "type of [" + k + "] is not correct"
      }
      //check max
      if(v.max)
        if(vo[k] && vo[k].length > v.max) throw "value of [" + k + "] over the column max size";
       
      //check value in the pick range
      if(v.pick && vo[k]) {
        if(_.indexOf(v.pick, vo[k]) < 0) throw "the value of [" + k + "] is not in the pick range"
      }
      //check execute map function
      if(v.map && vo[k])
        out[k] = v.map(vo[k]);
    }
  }
  return out;
}

透過上面設定的model的各項參數,讓filter function可以統一過濾所有的物件
把該留的欄位留下來,也可以做到過濾內容等等的功能...

使用範例: 
var vo = {
  "username": "xxx@gmail.com",
  "password": "test111",
  "nickname": "xxx",
  "phone":"02234567",
  "mobile":"0912345678",
  "address":"台北市內湖區堤頂大道二段",
  "lang": "cht",
  "created": 1403063028138,
  "user_type": "0",
  "uuid": "0e7d6d4d6-e3a0b9ea9ca7"
}
console.log(filter(vo, user));