【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--参数自动映射篇(6/8)...
文章目錄
前情概要
路由、action的掃描、發現、注冊搞定之后,后來我發現在我們的action里面獲取參數往往都是通過request對象來一個一個獲取。同樣的一行代碼我們不厭其煩的重復寫了無數次。遂想著那我們能不能像后端程序一樣做得更自動化一些呢?
所以,接下來我們再來完成一個比較重要的功能,那就是參數的自動綁定。
參數的自動綁定實現思路
依靠ts的裝飾器特性,我們能做在方法上,在類上,在方法的參數上,在類的屬性成員上通通可以加上裝飾器來存放一些額外的數據。那理論上我們在編碼階段就可以通過一定的手段把這個標記加載我們需要處理的方法、類、參數等上面,等到運行時的時候可以根據這些額外的參數來幫我們做一些重復性的工作。
參數的自動綁定實現---裝飾器實現
部分代碼,只貼了fromquery,其他幾個formbody,fromheader之類的基本一樣,都是調用makeActionParameterDescriptor方法
/*** 指示當前參數從request對象的query中解析* * @export* @param {(target?: any) => Function} type * @returns {Function} */ export function fromQuery(type: (target?: any) => Function): Function; /*** 指示當前參數從request對象的query中解析* * @export* @returns {Function} */ export function fromQuery(): Function {var thatArg = arguments;return function (target: Object, propertyKey: string, parameterIndex: number) {makeActionParameterDescriptor('query', thatArg, target, propertyKey, parameterIndex);} } function makeActionParameterDescriptor(parameterFromType: parameterFromType, thatArg: IArguments, target: Object, propertyKey: string, parameterIndex: number) {//非聲明在屬性和參數上if (!propertyKey) return;var paramType = undefined;var val = new ActionParamDescriptor();val.parameterName = propertyKey;val.target = target;val.parameterIndex = parameterIndex;val.parameterFromType = parameterFromType;val.parameterTypeType = 'simple'if (typeof parameterIndex === 'undefined') {//聲明在類的屬性上val.localtionType = 'classProperty'} else {//聲明在action的參數上val.localtionType = 'methodParameter'val.actionMethodName = propertyKey;val.parameterName = getArgs((target as any)[propertyKey])[parameterIndex];}//復雜類型if (thatArg.length > 0) {val.parameterTypeType = 'complex'val.parameterType = thatArg[0](target);}SetActionParamDescriptor(val); } function getArgs(func: Object) {//匹配函數括號里的參數 var method = func.toString();method = method.length > 500 ? method.substring(0, 500) : method;method = method.replace("\r|\n|\\s", "")var args = method.match(/.*?\(.*?\)/i);if (args == null) throw Error('can not match method parameters');method = args[0];method = method.replace(/.*?\(|\)/, "").replace(')', '');//分解參數成數組 var arr = method.split(",").map(function (arg) {//去空格和內聯注釋 return arg.replace(/\/\*.*\*\//, "").trim();}).filter(function (args) {//確保沒有undefineds return args;});return arr }ActionParamDescriptor 對象結構
export declare type parameterFromType = 'query' | 'body' | 'form' | 'header' | 'cookie' | 'auto' export class ActionParamDescriptor {/*** action參數的action名稱* * @type {string}* @memberof ActionParamDescriptor*/actionMethodName: string/*** 參數名稱* * @type {string}* @memberof ActionParamDescriptor*/parameterName: string/*** 參數所在類* * @type {Object}* @memberof ActionParamDescriptor*/target: Object/*** 參數類型的類別* * @type {('complex' | 'simple')}* @memberof ActionParamDescriptor*/parameterTypeType: 'complex' | 'simple'/*** 參數對象的類型(class)對象* * @type {Function}* @memberof ActionParamDescriptor*/parameterType: Function/*** 參數所在參數類別的順序* * @type {(number | undefined)}* @memberof ActionParamDescriptor*/parameterIndex: number | undefined/*** 當前參數屬性屬于什么類型* * @type {('classProperty'|'methodParameter')}* @memberof ActionParamDescriptor*/localtionType: 'classProperty' | 'methodParameter'/*** 標記參數應該從什么地方解析* * @type {parameterFromType}* @memberof ActionParamDescriptor*/parameterFromType: parameterFromType }參數的自動綁定實現---基本使用方法
可以在action上標記某一個參數從什么地方(query、form、body、cookie、header)進行解析,
也可以標記某個參數是一個復雜的查詢參數,可以指定這個參數的類型。
當然復雜的查詢class的每一個屬性都可以指定解析來源,當然也必須使用裝飾器來修飾一下,不然我們就沒法知道有這個屬性需要進行解析啦。
參數的自動綁定實現---參數的說明元數據保存
reflect-metadata 目前來說也還是ts的一個實驗性特性。可以用來輔助我們保存一些額外的數據。或者也可以理解成它是一個系統級別的靜態字典。
那我們把對參數的一些特別設置都通過reflect-metadata保存下來,其實這里我們自己使用一個對象來保存也是可以的。
參數的自動綁定實現---參數的自動解析和對象生成
嗯,大概是一些雜亂無章的代碼(^_^)。
主要思路:
需要說明的是,在這里有一個問題沒有解決。當參數指定類型為body的時候,我們沒有對參數進行更多的解析。也就意味著我申明的對象只有2個屬性,提交的body有3個屬性,最終在action里面的這個參數能拿到3個屬性。一直猶豫是否要做這里是否要做filter。
從后端的角度來說是毫無疑問的,不可能我一個class只聲明了2個屬性,而到運行時的時候能取出來3個屬性。這是不可能的。
但從前端的角度來講,這也許是一個比較好的特性。某些時候更省事情。比較接口部分參數透傳的時候之類的。
參數的自動解析大致就到這里了,嗯,這部分代碼可能有點小邏輯。又加上沒有注釋有點難理解。不過我覺得這樣挺好的,哈哈哈
轉載于:https://www.cnblogs.com/calvinK/p/nodejs-mvc-params-auto-mapping.html
總結
以上是生活随笔為你收集整理的【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--参数自动映射篇(6/8)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图解java工程师学习路线
- 下一篇: asp.net ajax控件工具集 Au