当前位置: 首页 > news >正文

南昌 提供网站设计 公司万网官网域名查询

南昌 提供网站设计 公司,万网官网域名查询,网站移动端怎么做的,黄骅市属于文章目录 前情概要 路由、action的扫描、发现、注册搞定之后#xff0c;后来我发现在我们的action里面获取参数往往都是通过request对象来一个一个获取。同样的一行代码我们不厌其烦的重复写了无数次。遂想着那我们能不能像后端程序一样做得更自动化一些呢#xff1f; 所以后来我发现在我们的action里面获取参数往往都是通过request对象来一个一个获取。同样的一行代码我们不厌其烦的重复写了无数次。遂想着那我们能不能像后端程序一样做得更自动化一些呢 所以接下来我们再来完成一个比较重要的功能那就是参数的自动绑定。 参数的自动绑定实现思路 依靠ts的装饰器特性我们能做在方法上在类上在方法的参数上在类的属性成员上通通可以加上装饰器来存放一些额外的数据。那理论上我们在编码阶段就可以通过一定的手段把这个标记加载我们需要处理的方法、类、参数等上面等到运行时的时候可以根据这些额外的参数来帮我们做一些重复性的工作。 在需要使用到的方法参数、类、属性上增加我们的特定标识标记当前参数需要自动解析并记录一些诸如类型拉、名称啦等的一些额外属性。在action的调用阶段根据规则先把参数解析好。在传递进去。完事儿这就是我们的参数自动绑定功能。参数的自动绑定实现---装饰器实现 部分代码只贴了fromquery,其他几个formbodyfromheader之类的基本一样都是调用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 simpleif (typeof parameterIndex undefined) {//声明在类的属性上val.localtionType classProperty} else {//声明在action的参数上val.localtionType methodParameterval.actionMethodName propertyKey;val.parameterName getArgs((target as any)[propertyKey])[parameterIndex];}//复杂类型if (thatArg.length 0) {val.parameterTypeType complexval.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的每一个属性都可以指定解析来源,当然也必须使用装饰器来修饰一下不然我们就没法知道有这个属性需要进行解析啦。 import { BaseController, post, fromQuery, fromBody, fromCookie, fromHeader, property } from ../src/index export class demoActionBodyParams {id: string;name: string;pageSize: number;body: {req_bb: string} } export class demoActionQueryParams {property()id: string;property()name: string;property()pageSize: number;fromCookie()cookieName: string;fromHeader()headerName: string;fromBody()body: any; } export class demoController extends BaseController {post()demoAction(fromQuery(type demoActionQueryParams) query: demoActionQueryParams,fromQuery() p2: string,fromBody() req_body: demoActionBodyParams) {return { query, p2, req_body }} } 参数的自动绑定实现---参数的说明元数据保存 reflect-metadata 目前来说也还是ts的一个实验性特性。可以用来辅助我们保存一些额外的数据。或者也可以理解成它是一个系统级别的静态字典。 那我们把对参数的一些特别设置都通过reflect-metadata保存下来其实这里我们自己使用一个对象来保存也是可以的。 const request_params_auto_bind_MetadataKey Symbol(request_params_auto_bind_MetadataKey); export function SetActionParamDescriptor(val: ActionParamDescriptor) {(val as any).targetName val.target.constructor.nameif (val.parameterType) (val as any).parameterTypeName val.parameterType.nameconsole.log(SetActionParamDescriptor, JSON.stringify(val));var arr: ActionParamDescriptor[] [];if (val.localtionType methodParameter) {arr Reflect.getMetadata(request_params_auto_bind_MetadataKey, val.target, val.actionMethodName) || [];arr.push(val);Reflect.defineMetadata(request_params_auto_bind_MetadataKey, arr, val.target, val.actionMethodName);} else {arr Reflect.getMetadata(request_params_auto_bind_MetadataKey, val.target) || [];arr.push(val);Reflect.defineMetadata(request_params_auto_bind_MetadataKey, arr, val.target);} } 参数的自动绑定实现---参数的自动解析和对象生成 嗯大概是一些杂乱无章的代码(^_^)。 主要思路 获得当前action的参数描述对象根据参数描述对象中的配置来解析参数就这么简单完事儿//开始参数的自动解析操作var agrs bindActionParameter(desc.ControllerType, desc.ControllerTypeName, desc.ActionType, desc.ActionName, req)function bindActionParameter(controllerType: Function, controllerName: string, actionType: Object, actionName: string, req: core.Request) { //获得当前action的所有参数描述对象var arr Reflect.getMetadata(request_params_auto_bind_MetadataKey, controllerType.prototype, actionName) || [] as ActionParamDescriptor[];var args [arr.length];for (let index 0; index arr.length; index) {args[arr[index].parameterIndex as number] getParameterValue(req, arr[index], arr[index])//循环挨个进行解析}return args; } function bindClassParameter(req: core.Request, target: any, methodParmeterdesc: ActionParamDescriptor): any {var arr Reflect.getMetadata(request_params_auto_bind_MetadataKey, target.prototype) as ActionParamDescriptor[];var obj new target();for (let index 0; index arr.length; index) {var desc arr[index];obj[desc.parameterName] getParameterValue(req, desc, methodParmeterdesc);}return obj; } function getParameterValue(req: core.Request, desc: ActionParamDescriptor, methodParmeterdesc: ActionParamDescriptor): any {//判断当前action的参数是基本类型参数还是复杂类型参数。如果是复杂类型就走class绑定逻辑。if (desc.parameterTypeType simple || (desc.localtionType methodParameter desc.parameterFromType body)) {return getparameterInRequest(desc.parameterFromType, desc.parameterName, req, methodParmeterdesc);} else if (desc.parameterTypeType complex) {return bindClassParameter(req, desc.parameterType, methodParmeterdesc)}else throw Error(not support parameter type desc.parameterTypeType) } //根据参数的不同配置进行不同解析。 function getparameterInRequest(fromType: parameterFromType, parameterName: string, req: core.Request, methodParmeterdesc: ActionParamDescriptor): any {switch (fromType) {case query:return getCompatibleParam(req.query, parameterName)case body:return req.bodycase header:return getCompatibleParam(req.headers, parameterName)case cookie:return getCompatibleParam(req.cookies, parameterName)case form:return getCompatibleParam(req.body, parameterName)case auto:return getparameterInRequest(methodParmeterdesc.parameterFromType, parameterName, req, methodParmeterdesc);}return undefined; } //忽略参数的大小写问题。 function getCompatibleParam(obj: any, propertyName: string) {var lower propertyName.toLowerCase();for (const key in obj) {if (obj.hasOwnProperty(key) key.toLowerCase() lower) {return obj[key];}} } 需要说明的是在这里有一个问题没有解决。当参数指定类型为body的时候我们没有对参数进行更多的解析。也就意味着我申明的对象只有2个属性提交的body有3个属性最终在action里面的这个参数能拿到3个属性。一直犹豫是否要做这里是否要做filter。 从后端的角度来说是毫无疑问的不可能我一个class只声明了2个属性而到运行时的时候能取出来3个属性。这是不可能的。 但从前端的角度来讲这也许是一个比较好的特性。某些时候更省事情。比较接口部分参数透传的时候之类的。 参数的自动解析大致就到这里了嗯这部分代码可能有点小逻辑。又加上没有注释有点难理解。不过我觉得这样挺好的哈哈哈 转载于:https://www.cnblogs.com/calvinK/p/nodejs-mvc-params-auto-mapping.html
http://www.pierceye.com/news/13710/

相关文章:

  • 广州中国建设银行网站首页招考网站开发
  • 苏州网站建设教程语音网站怎么做
  • 彩票网站开发合法吗网站建设公司哪里找
  • 专业手机移动网站建设公益网站模板
  • 建设工程教育网好还是环球网站好张北北京网站建设
  • 网站开发软件开发培训html 社区网站 模板
  • 自定义网站建站公司潍坊企业网络推广
  • 可以做微信推文的网站百度产品有哪些
  • 企业网站收费标准vue做移动端网站与pc端有什么区别
  • 做空调的网站网站底部设计源码
  • 网站如何换域名灰色词排名上首页
  • 更改网站备案负责人教育门户网站建设
  • 专业网站建设 公司哪家好常州网站建设最易
  • 网站的页面结构网站建设渠道合作
  • 直播课网站怎样做的法国vps 安装wordpress
  • 网站建设需求信息服饰的网站建设
  • 威海外贸网站建设联系方式南京我爱我家网站建设新村二手房
  • 杭州做网站比较好的公司下列哪个软件属于网页制作软件
  • 西安做企业网站哪家做的好航运网站建设计划书
  • tp3企业网站开发百度云蜂箱尺寸与制作图片
  • 图片存放网站做链接做评测好的视频网站有哪些
  • 如何做网站链接分享朋友圈做app模板网站有哪些
  • 网站建设策划书心得做网站要学会那些
  • 建网站能赚钱吗赚多少图片识别
  • 石家庄专业做网站网页设计思路说明200字
  • html5开发wap网站flash网站效果
  • 简易网站建设维护顺企网官网
  • 知名的产品设计网站东莞公司网站开发
  • 做网站用dw还是vs帮做简历哪个网站好
  • 潍坊做网站公司漯河市建设监理协会网站