|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
我之所以想学。NET,是因为一直觉的BILLGATES好厉害,希望有一天能去微软,虽然现在还距离遥远,呵呵:)有良多时分,必要我们在代码中实行良多反复的事情,这时候候要触及到怎样利用可复用的办法来办理反复性成绩。
好比一个项目办理体系,请求在分歧的页面的分歧地位都能调剂义务的预算事情量,并且要利用Ajax办法(由于每次调剂后都要及时看到总计),应当怎样做呢?
从操纵步骤上看,大抵分为这么几步:
0.显现以后的值(应当看上往能修正的模样)
1.点击以后值,弹出一个小窗口,里边是大概的取值(好比0.25,0.5,1,2,3,5……天),且显现为链接(因而用户会往点)
2.点击个中一个链接(Ajax链接),实行某个Ajax功效
3.若乐成,应当前往新的数值
4.假如必要,更新某些盘算了局(如调剂后的总工时等)
大抵营业界面以下:
右侧绿框中显现的就是以后值(高低另有良多这类以后值),一切事情完成后,必要革新左边带暗影地区(第一是黄框中的总额;别的因为这个义务还显现在右边的地区中,以是第二还要同步更新右边上面的蓝框中的数值)。
要一步一步地完成这些手艺上其实不太难,不过是
0.把以后值显现为一个DIV
1.点击以后值,用jquerytoggle出一个另外一个平常埋没的DIV,里边放好了一切大概的取值
这些“大概的值”应当是用某种办法读取来的,不然简单乱;每一个值,都是一个Ajax链接
2.点击个中一个链接(Ajax链接),实行某个Ajax功效,这个功效应当是好比Efforts/AjaxSetEffortPlanned?itemID=XX&effortPlanned=YY之类的
3.若乐成,应当前往新的数值,以是把1中的每一个Ajax链接的UpdateTargetID设为0中的DIV便可
4.乐成返来后革新右边的地区,从头盘算和实际(这里假定已有了个js函数叫做functionrefreshLeftPad())
可是,假如有良多页面都要这个功效,并且今后另有其他的相似功效(调剂以后卖力人、完成形态之类的……),那末代码就会痴肥反复,怎样办呢?封装。
封装的准绳
上面这个准绳是我2001年的徒弟关宏超说的,厥后一向被我们发扬光年夜,叫做“最小信息准绳”:
最小信息准绳:办法接口应只传送最必需的营业信息。
包含两个层面:
1.手艺数据不要传送
2.营业数据不克不及反复
究竟说的是甚么意义呢?
[csharp]
- MvcHtmlStringajaxValue=SFCUI.AjaxValue(Model.ID,effortValue.ToString(),AjaxValue.ValuesKeys.EffortPlanned,"/SFC/Efforts/AjaxSetEffortPlanned?itemID="+Model.ID+"&value={0}",ajaxOnSuccess:"refreshLeftPad");
MvcHtmlStringajaxValue=SFCUI.AjaxValue(Model.ID,effortValue.ToString(),AjaxValue.ValuesKeys.EffortPlanned,"/SFC/Efforts/AjaxSetEffortPlanned?itemID="+Model.ID+"&value={0}",ajaxOnSuccess:"refreshLeftPad");
先重温一下准绳:
最小信息准绳:办法接口应只传送最必需的营业信息。
包含两个层面:
1.手艺信息不要表露
2.营业信息不克不及反复
营业信息剖析
先别管手艺成绩,想想做这个事变必要哪些数据才干完成?
1.本来的值是几(显现用)
2.大概的值有哪些(选择用)
3.点一个值后,应当实行甚么操纵(这个是中心营业)
4.前往后做甚么(革新用)
另有一些成绩哪往了?
5.前往的值革新到那里?这个挪用者不论,他让我们布置,显现也是我们显现(好比一个DIV),革新天然就是革新我们显现的谁人地位。
6.假如前往后甚么都不做怎样办?看着办。
终极办法接口计划为:
[csharp]
- publicstaticMvcHtmlStringAjaxValue(intid,stringvalue,string[]values,stringurlFormat,stringajaxOnSuccess=null)
- 由于要显现良多个这类AjaxValue,用ID来辨别。
publicstaticMvcHtmlStringAjaxValue(intid,stringvalue,string[]values,stringurlFormat,stringajaxOnSuccess=null)怎样多了个id?由于要显现良多个这类AjaxValue,用ID来辨别。
怎样多了个ID?
urlFormat是甚么?他是用来界说天生的Ajax链接的格局的,请看上面的挪用(稍微存在一些成绩的):
[csharp]
- @SFCUI.AjaxValue(story.ID,effortValue.ToString(),Effort.EffortPlannedValues,"/SFC/Efforts/AjaxSetEffortPlanned?itemID="+story.ID+"&value={0}",ajaxOnSuccess:"refreshLeftPad");
@SFCUI.AjaxValue(story.ID,effortValue.ToString(),Effort.EffortPlannedValues,"/SFC/Efforts/AjaxSetEffortPlanned?itemID="+story.ID+"&value={0}",ajaxOnSuccess:"refreshLeftPad");
这几个参数按次申明是:story.ID修正谁的值,effrotValue以后值,...EffortPlannedValues大概的值,"...."AjaxLink的href格局{0}里边将来将放着被选择的value,ajaxOnSuccess是准确前往挪用的函数。
接口计划准绳的剖析
从实际上说,在任何cshtml中安排这句话,就具有了一切的营业信息,剩下的满是手艺成绩,在这个办法里边办理,表面一概不论,这就叫做“手艺信息不要表露”的子准绳。
怎样后面说“稍微存在一些成绩”呢?由于story.ID在这个里边呈现了两遍,第一次是一个整数参数传送出来了,第二次是用来天生了urlFormat传送出来了,第二次过剩,应当改成:
[csharp]
- @SFCUI.AjaxValue(story.ID,effortValue.ToString(),Effort.EffortPlannedValues,"/SFC/Efforts/AjaxSetEffortPlanned?itemID={0}&value={1}",ajaxOnSuccess:"refreshLeftPad");
@SFCUI.AjaxValue(story.ID,effortValue.ToString(),Effort.EffortPlannedValues,"/SFC/Efforts/AjaxSetEffortPlanned?itemID={0}&value={1}",ajaxOnSuccess:"refreshLeftPad");
如许里边在0安排id,1安排value,就可以拼集出AjaxLink来。
如今,再删除任何一个字母和标点标记信息就不敷了,这就叫做“营业信息不克不及反复”子准绳。
把握了这个准绳,就可以在第一工夫确认接口的参数(自己喜好称之为“表面”),然后完工编写。
固然偶然候不克不及第一次就写出最简洁的接口,那末能够实验先“散装”一下,是一个函数,仍是一堆DIV,先写出来再说,写完了,再封装成最简情势。
下一篇,会大抵说一下AjaxLink里边的完成。
之前讲到,办法声明为:
[csharp]
- @SFCUI.AjaxValue(story.ID,effortValue.ToString(),Effort.EffortPlannedValues,"/SFC/Efforts/AjaxSetEffortPlanned?itemID="+story.ID+"&value={0}",ajaxOnSuccess:"refreshLeftPad");
@SFCUI.AjaxValue(story.ID,effortValue.ToString(),Effort.EffortPlannedValues,"/SFC/Efforts/AjaxSetEffortPlanned?itemID="+story.ID+"&value={0}",ajaxOnSuccess:"refreshLeftPad");
挪用的例子:
[csharp]
- @SFCUI.AjaxValue(story.ID,effortValue.ToString(),Effort.EffortPlannedValues,"/SFC/Efforts/AjaxSetEffortPlanned?itemID={0}&value={1}",ajaxOnSuccess:"refreshLeftPad");
@SFCUI.AjaxValue(story.ID,effortValue.ToString(),Effort.EffortPlannedValues,"/SFC/Efforts/AjaxSetEffortPlanned?itemID={0}&value={1}",ajaxOnSuccess:"refreshLeftPad");
感到上toggle、弹出菜单、UpdateTargetID甚么的都没有啊,怎样能完成?
这就是计划的一种主要准绳:把一切手艺细节都埋没在完成的外部。
函数外部的计划
上面的代码仅作示例,与我本人用的不太一样,简化了一下,只为申明成绩。
[csharp]
- publicstaticMvcHtmlStringAjaxValue(intid,stringvalue,string[]values,stringurlFormat,stringajaxOnSuccess=null)
- {
- stringajaxUpdateTargetID="ValueOf"+id;
- stringinnerHtml=null;
- //Buildthedivtoshowthefinalvalue.
- TagBuildertheValue=newTagBuilder("div");//这个是安排原始数值的DIV,往后更新的也是它,ID在后面天生好了。
- theValue.InnerHtml=value;
- ...
- //BuildtheajaxLinktopopupthemenuofvaluestobeselected.
- TagBuilderajaxLink=newTagBuilder("div");//这个是在Value前面放一个能够点的小图片,点一下就会弹出菜单
- ...ajaxLink.AddCSSClass("clickshow");//这个是我本人界说的Class,申明点击它,会弹出一样工具,就是是$("#clickshowBodyOfAjaxLinkOf"+$(this).attr(id)).show()。
- innerHtml+=ajaxLink.ToString();
- //Buildthedivtoshowthepopupmenu;anda"clickshowbody"containertohidethemenuwhenmouseleft.
- TagBuildercontent=newTagBuilder("div");//这个是平常埋没,点击后会弹出的谁人菜单。
- ...//这里埋没的对照多,由于我挪用了良多我本人的函数好比ImageLink()等,写出来也看不到细节。
- ...//大抵就是:在菜单里边foreach(varvinvalues),用id和每一个v,string.Format(urlFormat,id,v)出一个AjaxLink来。
- ...//假如OnSuccess不是null,记得AjaxLink里边要放上OnSuccess。
- ...//关头代码:imglink(是个<a>tagbuilder).MergeAttribute("onclick","Sys.Mvc.AsyncHyperlink.handleClick(this,newSys.UI.DomEvent(event),{insertionMode:Sys.Mvc.InsertionMode.replace,updateTargetId:"+ajaxUpdateTargetID+",onSuccess:Function.createDelegate(this,"+ajaxOnSuccess+")});");
- innerHtml+=clickshowbody.ToString();
- returnnewMvcHtmlString(innerHtml);}
- </a>
publicstaticMvcHtmlStringAjaxValue(intid,stringvalue,string[]values,stringurlFormat,stringajaxOnSuccess=null){stringajaxUpdateTargetID="ValueOf"+id;stringinnerHtml=null;//Buildthedivtoshowthefinalvalue.TagBuildertheValue=newTagBuilder("div");//这个是安排原始数值的DIV,往后更新的也是它,ID在后面天生好了。theValue.InnerHtml=value;...//BuildtheajaxLinktopopupthemenuofvaluestobeselected.TagBuilderajaxLink=newTagBuilder("div");//这个是在Value前面放一个能够点的小图片,点一下就会弹出菜单...ajaxLink.AddCssClass("clickshow");//这个是我本人界说的Class,申明点击它,会弹出一样工具,就是是$("#clickshowBodyOfAjaxLinkOf"+$(this).attr(id)).show()。innerHtml+=ajaxLink.ToString();//Buildthedivtoshowthepopupmenu;anda"clickshowbody"containertohidethemenuwhenmouseleft.TagBuildercontent=newTagBuilder("div");//这个是平常埋没,点击后会弹出的谁人菜单。...//这里埋没的对照多,由于我挪用了良多我本人的函数好比ImageLink()等,写出来也看不到细节。...//大抵就是:在菜单里边foreach(varvinvalues),用id和每一个v,string.Format(urlFormat,id,v)出一个AjaxLink来。...//假如OnSuccess不是null,记得AjaxLink里边要放上OnSuccess。...//关头代码:imglink(是个<a>tagbuilder).MergeAttribute("onclick","Sys.Mvc.AsyncHyperlink.handleClick(this,newSys.UI.DomEvent(event),{insertionMode:Sys.Mvc.InsertionMode.replace,updateTargetId:"+ajaxUpdateTargetID+",onSuccess:Function.createDelegate(this,"+ajaxOnSuccess+")});");innerHtml+=clickshowbody.ToString();returnnewMvcHtmlString(innerHtml);}</a>
如许,函数里边就把安排Value的DIV(也就是往后会被更新的谁人)、弹出菜单、弹出菜单上应当写的工具、点击后该干甚么、弹出后该干甚么等等都处置了,扔到那里都事情。
上面是点击后弹出的效果:
更庞大的接口
下面的例子基础上办理了复杂的列表式弹出窗口的情形,假如弹出来的工具对照庞大怎样办?好比我想把一个义务分派给我卖力的组或我介入的组的某个组员,并且不但愿这些组员间接按姓名分列(假定我记不住这些人),但愿能出现出一个上面如许的界面来:
图中点一下人名,就可以把这个义务分派给这团体。
这个时分万万别先想手艺完成手腕,而是先要想一下:究竟有几个营业信息要处置?实在就4个:
1.哪一个义务?义务的ID
2.甚么信息要改?“以后卖力人”
3.可选职员有哪些?“我的组(我卖力办理的和我介入的)”
4.设置好了要做点甚么?“革新一下屏幕”(次要是为了让更新后的内容承受一下Document.Ready里边的JS从头刷一下)
以是函数声明是:
[csharp]
- publicstaticMvcHtmlStringAjaxSDCValue(Itemitem,intsdcTypeValue,AjaxValue.ValuesKeysvaluesKey,stringajaxOnSuccess=null)
publicstaticMvcHtmlStringAjaxSDCValue(Itemitem,intsdcTypeValue,AjaxValue.ValuesKeysvaluesKey,stringajaxOnSuccess=null)
item是谁人义务
sdcTypeValue是之前界说好的自界说字段的值(不是为了这个AjaxValue界说的,SDC=SystemDefinedColumn体系自界说字段)
AjaxValue.ValuesKey是个enum略微庞大一点。之前老是间接输出string[]来代表将来的值,如今有多是User[]……等等,以是爽性传送一个enum由函数外部判别此次是找甚么,里边再具体处置。
urlFormat哪往了?因为AjaxSDCValue是我们专门用来处置体系自界说字段的,以是urlFormat是一致的,请看函数外部:
[csharp]
- publicstaticMvcHtmlStringAjaxSDCValue(Itemitem,intsdcTypeValue,AjaxValue.ValuesKeysvaluesKey,stringajaxOnSuccess=null)
- {
- stringvalue=item.ReadSDCValueOf(sdcTypeValue);
- stringurlFormat="/SFC/Items/AjaxSetSDCValue?<itemID={0}&sdcTypeValue="+SDCType.USER_CURRENT_OWNER+"&value={0}";
- returnAjaxValue(item.ID,value,valuesKey,urlFormat,ajaxOnSuccess);}
publicstaticMvcHtmlStringAjaxSDCValue(Itemitem,intsdcTypeValue,AjaxValue.ValuesKeysvaluesKey,stringajaxOnSuccess=null){stringvalue=item.ReadSDCValueOf(sdcTypeValue);stringurlFormat="/SFC/Items/AjaxSetSDCValue?<itemID={0}&sdcTypeValue="+SDCType.USER_CURRENT_OWNER+"&value={0}";returnAjaxValue(item.ID,value,valuesKey,urlFormat,ajaxOnSuccess);}
实践上完整利用本来的函数AjaxValue也能完成,可是向用户表露了过量的手艺细节(特别是构成urlFormat的式子太庞大),完整是用户不该该体贴的。
/SFC/items/AjaxSetSDCValue会把Item的USER_CURRENT_OWNER字段设置为value的值。
弹出的庞大菜单哪来的?我们总结了一下,发明AjaxValue大抵大概弹出以下几种工具:
1.最基础的一串字符串(本来谁人string[],能够处置可用的预估值、残剩工夫值、消费工夫值……)
2.我的组的职员(分派义务、分派Bug、布置值班、布置休假……)
3.……
urlFormat分歧点击后的功效就分歧,但上述菜单的布局和表面每次都不异。
以是就做了一个AjaxController.PopupAjaxValuesMenu,会依据传出去的AjaxValue.ValuesKey这个enum来判别弹出哪一个菜单(包含筹办菜单中的数据),特地把urlFormat也传出来。
回忆
计划和调试这一堆工具仍是花了2地利间的,可是今后不再用见到约莫每次都要50行摆布的C#/Html代码了。
当将来的保护者看到这段代码时:
[csharp]@SFCUI.AjaxSDCValue(Story,SDCType.USER_CURRENT_OWNER,AjaxValue.ValuesKeys.UsersMyTeams,ajaxOnSuccess:"function(){refreshStoryPad("+Story.ID+");}",imageUrl:"/SFC/Users/Details16.png")
他会想:“哦,这里要把Story的CurrentOwner调剂为……我的Team中的一团体,假如乐成了会来革新这条故事。并且,后面仿佛还显现了个头像图标!”
这比面临50行漫天飞的代码要恬逸多了。
写到最初,俄然想起来10年前总结过的另外一句话:
封装的最高地步,就是用和天然言语一样多的笔墨写完挪用代码,剩下的全体藏匿起来。
有专家说:net网页编程不是跨平台,net网页编程就是平台,这很好的定义了net网页编程的特点。有了net网页编程,你只需要等待net网页编程平台在新平台上移植。这还不错吧!只是,net网页编程不是一个平台,而是多个平台。你需要在这个net网页编程平台移植到另一个net网页编程平台。 |
|