ASP.NET网页设计asp.net MVC代码示例:体系设置(View复用示例)仓酷云
一般的指的.net就是跟net网页编程相对的那种,主要是做企业级应用的。你如果想学这个,主要就是学C#和数据库。(ASP.NET好像很重要的,应该也要学的,ASP.NET上好像可以结合VB和C#等多种语言,但是微软主推C#)目次(?)[-][*]功效简介
[*]开辟历程
[*]第一步:开辟出StoryTreeType部分的Model代码
[*]第二步:完成StoryTreeType的View
[*]第三步:为StatusList的Model部分“打草稿”
[*]第四步:将StoryTreeType和StatusList改写为一个基类的派生类
[*]第五步:将处置StoryTreeType的View改写为同时能够处置StatusList的
[*]先启示一个第二疆场:
[*]一点点把StoryTreeType1中的StoryTreeType的影子抹失落
[*]第六步:到场对StatusList的处置
[*]后续及总结
[*]后续
[*]总结
功效简介
终极功效如图:
下面一行两张图,是火星人的用户故事树设置界面,在每一个用户故事的前面都有一个按钮(悬停可见),点击后呈现操纵菜单,个中一部分是新建上级故事菜单。
若用户选择左边,菜单上只包含一个项目“通用故事”;若选择右边,则包含良多故事(受以后故事范例的束缚,这个对照庞大今后再说)。
这段代码,等一下将会呈现关头字“StoryTreeType”,左边叫做“Simple”(复杂树),右边叫做“Leveled”(品级树)。
上面一行两张图,是火星人的形态链设置界面,在下面提到的操纵菜单上,除能新建故事以外,还能将以后故事转移到别的一个形态。
若用户选择左边,菜单上只包含与开辟相干的形态(新建-待开辟-开辟中-开辟终了-部署终了);做选择右边,则会呈现一切形态(新建后有审批等环节,而部署历程也包含多个形态)。
这段代码,等一下将会呈现关头字“StatusList”,左边叫做“DevelopmentOnly”(仅包括研发形态),右边叫做“All”(一切)。
很明显,不但是这两排界面很相似,这四个界面和面前的模子都十分邻近,上面谈谈怎样以最小代码完成这个设置功效。
开辟历程
Controller部分的代码略过,重点看Model和View的封装。
第一步:开辟出StoryTreeType部分的Model代码
[*]publicpartialclassProduct
[*]{
[*]publicconststringUserDefaultProductIDKey="DefaultProductID";
[*]
[*]//StoryTreetype(Simple,Leveled,etc.)
[*]publicconststringStoryTreeTypeKey="StoryTreeType";
[*]publicenumStoryTreeTypes
[*]{
[*]Simple=0,
[*]Leveled=1
[*]}
[*]
[*]publicstaticreadonlyStoryTreeTypes[]StoryTreeTypeValues={StoryTreeTypes.Simple,StoryTreeTypes.Leveled};
[*]publicstaticreadonlystring[]StoryTreeTypeTexts={"缺省(利用复杂父子干系构成故事树)","利用体系界说的故事品级构成故事树"};
[*]
[*]publicStoryTreeTypesStoryTreeType
[*]{
[*]get{return(StoryTreeTypes)Config.ReadValueAsInt(StoryTreeTypeKey,"$"+ID);}
[*]}
[*]
[*]publicstringStoryTreeTypeText
[*]{
[*]get{returnStoryTreeTypeTexts;}
[*]}
[*]}
publicpartialclassProduct{publicconststringUserDefaultProductIDKey="DefaultProductID";//StoryTreetype(Simple,Leveled,etc.)publicconststringStoryTreeTypeKey="StoryTreeType";publicenumStoryTreeTypes{Simple=0,Leveled=1}publicstaticreadonlyStoryTreeTypes[]StoryTreeTypeValues={StoryTreeTypes.Simple,StoryTreeTypes.Leveled};publicstaticreadonlystring[]StoryTreeTypeTexts={"缺省(利用复杂父子干系构成故事树)","利用体系界说的故事品级构成故事树"};publicStoryTreeTypesStoryTreeType{get{return(StoryTreeTypes)Config.ReadValueAsInt(StoryTreeTypeKey,"$"+ID);}}publicstringStoryTreeTypeText{get{returnStoryTreeTypeTexts;}}}注重这段代码里边有一个叫做Config的类,它卖力把分歧的设置写到数据库中的一个大众内外边,因而为了完成这个功效,我们其实不必要会商数据存储成绩。
这得益于火星人之前已封装好的浩瀚功效。
第二步:完成StoryTreeType的View
注重上面的代码,已将StroyTreeType的两品种型举行了Foreach轮回处置,而不是写逝世在里边。
偶然候会以为只要两种,还做甚么轮回,但假如不轮回就必要两段很靠近的代码,调试和保护都很费力。并且一旦养成这类习气,很简单把全部软件都写散了。
[*]@foreach(vartypeinProduct.StoryTreeTypeValues)
[*]{
[*]<tdstyle="border:none;">
[*]<divclass="help-sample">
[*]<table>
[*]<tr>
[*]<tdstyle="border:none;width:500px;">
[*]@MFCUI.Image("","/Products/StoryTree/Index16.png")<b>@Product.StoryTreeTypeTexts[(int)type]</b>
[*]@if(Model.StoryTreeType==type)
[*]{
[*]<b>[以后设置]</b>
[*]}
[*]else
[*]{
[*]@MFCUI.Link("[启用]","/MFC/Configs/AjaxSet?key="+Product.StoryTreeTypeKey+"&value="+(int)type+"&user=$"+Model.ID,returnTo:this)
[*]@:
[*]}
[*]<table>
[*]<tr>
[*]<tdstyle="border:none;width:200px;">
[*]@RenderPage("~/Areas/DLC/Views/Products/ManagementMethod/StoryTreeTypes/_"+Model.StoryTreeType+".cshtml")
[*]</td>
[*]<tdstyle="border:none;">
[*]@MFCUI.Image("","/Products/Products/ManagementMethods/_"+type+"Example.png")<br/><br/>
[*]</td>
[*]</tr>
[*]</table>
[*]</td>
[*]</tr>
[*]</table>
[*]</div>
[*]</td>
[*]}
@foreach(vartypeinProduct.StoryTreeTypeValues){<tdstyle="border:none;"><divclass="help-sample"><table><tr><tdstyle="border:none;width:500px;">@MFCUI.Image("","/Products/StoryTree/Index16.png")<b>@Product.StoryTreeTypeTexts[(int)type]</b>@if(Model.StoryTreeType==type){<b>[以后设置]</b>}else{@MFCUI.Link("[启用]","/MFC/Configs/AjaxSet?key="+Product.StoryTreeTypeKey+"&value="+(int)type+"&user=$"+Model.ID,returnTo:this)@:}<table><tr><tdstyle="border:none;width:200px;">@RenderPage("~/Areas/DLC/Views/Products/ManagementMethod/StoryTreeTypes/_"+Model.StoryTreeType+".cshtml")</td><tdstyle="border:none;">@MFCUI.Image("","/Products/Products/ManagementMethods/_"+type+"Example.png")<br/><br/></td></tr></table></td></tr></table></div></td>}注重
1.这段代码里边有一个叫做“/MFC/Configs/AjaxSet?..."的挪用,这个挪用将间接完成设置事情(写进数据库),并立即革新以后页(注重有个“returnTo:this,是火星人中回到以后页的封装)。
2.最下面的题目(“缺省(利用复杂父子干系构成故事树)”和“利用体系界说的故事品级构成故事树”)、图片(最上面一个@MFCUI.Image())都是在这个页面写出来的
3.两个RenderPage用于显现“长处”“弱点”“倡议”这些不同对照年夜的笔墨,分离存储在两个文件里边,文件名是在RenderPage里边用Model.StoryTreeType拼装出来的。
2和3标明了在MVC的View中的几个很主要的封装准绳:
A.类似的部分必定要For轮回出来在一个View经由过程拼接中办理
B.稍微分歧的参数利用变量拼接出来
C.图片、PartialView的定名要与变量对应,如许便利拼接
D.最年夜的分歧,利用PartialView来处置。
第三步:为StatusList的Model部分“打草稿”
(写这篇博客的时分,我的代码方才写到这里,为了能拷贝到一点“草稿代码”,不等编码失掉考证就入手下手写了)
做了良多年的封装,感到最疾速的办法,仍旧是探索性封装,也就是先写出一个部分(如下面的StoryTreeType),然后拷贝别的一个类似的部分(以下面的StatusList),然后察看其类似点和分歧点,然后才举行封装。
与间接在开首就计划封装比拟,这类办法对照简单进修和承受,对职员的请求也绝对较低。自己编程这么多年,仍是没掌控在一切情形下都面临空屏幕间接先写底层,然后派生出子类。
注重StatusList部分的代码是间接拷贝、粘贴、修正出来的,它们是“草稿代码”,用来察看封装要点的。往后将被代替。
[*]publicpartialclassProduct
[*]{
[*]publicconststringUserDefaultProductIDKey="DefaultProductID";
[*]
[*]//StoryTreetype(Simple,Leveled,etc.)
[*]publicconststringStoryTreeTypeKey="StoryTreeType";
[*]publicenumStoryTreeTypes
[*]{
[*]Simple=0,
[*]Leveled=1
[*]}
[*]
[*]publicstaticreadonlyStoryTreeTypes[]StoryTreeTypeValues={StoryTreeTypes.Simple,StoryTreeTypes.Leveled};
[*]publicstaticreadonlystring[]StoryTreeTypeTexts={"缺省(利用复杂父子干系构成故事树)","利用体系界说的故事品级构成故事树"};
[*]
[*]publicStoryTreeTypesStoryTreeType
[*]{
[*]get{return(StoryTreeTypes)Config.ReadValueAsInt(StoryTreeTypeKey,"$"+ID);}
[*]}
[*]
[*]publicstringStoryTreeTypeText
[*]{
[*]get{returnStoryTreeTypeTexts;}
[*]}
[*]
[*]//Statuslisttype(DevelopmentOnly,All,etc.)
[*]publicconststringStatusListTypeKey="StatusListType";
[*]publicenumStatusListTypes
[*]{
[*]DevelopmentOnly=0,
[*]Allowed=1
[*]}
[*]
[*]publicstaticreadonlyStatusListTypes[]StatusListTypeValues={StatusListTypes.DevelopmentOnly,StatusListTypes.Allowed};
[*]publicstaticreadonlystring[]StatusListTypeTexts={"缺省(只显现开辟相干的形态)","利用用户自界说的同意形态"};
[*]
[*]publicStatusListTypesStatusListType
[*]{
[*]get{return(StatusListTypes)Config.ReadValueAsInt(StatusListTypeKey,"$"+ID);}
[*]}
[*]
[*]publicstringStatusListTypeText
[*]{
[*]get{returnStoryTreeTypeTexts;}
[*]}
[*]}
publicpartialclassProduct{publicconststringUserDefaultProductIDKey="DefaultProductID";//StoryTreetype(Simple,Leveled,etc.)publicconststringStoryTreeTypeKey="StoryTreeType";publicenumStoryTreeTypes{Simple=0,Leveled=1}publicstaticreadonlyStoryTreeTypes[]StoryTreeTypeValues={StoryTreeTypes.Simple,StoryTreeTypes.Leveled};publicstaticreadonlystring[]StoryTreeTypeTexts={"缺省(利用复杂父子干系构成故事树)","利用体系界说的故事品级构成故事树"};publicStoryTreeTypesStoryTreeType{get{return(StoryTreeTypes)Config.ReadValueAsInt(StoryTreeTypeKey,"$"+ID);}}publicstringStoryTreeTypeText{get{returnStoryTreeTypeTexts;}}//Statuslisttype(DevelopmentOnly,All,etc.)publicconststringStatusListTypeKey="StatusListType";publicenumStatusListTypes{DevelopmentOnly=0,Allowed=1}publicstaticreadonlyStatusListTypes[]StatusListTypeValues={StatusListTypes.DevelopmentOnly,StatusListTypes.Allowed};publicstaticreadonlystring[]StatusListTypeTexts={"缺省(只显现开辟相干的形态)","利用用户自界说的同意形态"};publicStatusListTypesStatusListType{get{return(StatusListTypes)Config.ReadValueAsInt(StatusListTypeKey,"$"+ID);}}publicstringStatusListTypeText{get{returnStoryTreeTypeTexts;}}}第四步:将StoryTreeType和StatusList改写为一个基类的派生类
说假话,这个改写历程失利了,5分钟后发明,由于每行代码都有分歧的地方,即便改写乐成,初始化代码不比这些代码少。
并且还要冒着保持enum的风险,以是停止了改写企图。
第五步:将处置StoryTreeType的View改写为同时能够处置StatusList的
良多老手在这个时分大概会间接入手下手下手,但上面先容一下一个小技能:
1.先启示一个第二疆场:
[*]<tableclass="noborder">
[*]<tr>
[*]@RenderPage("~/Areas/Products/Views/Products/SetManagementMethods/_StoryTreeType.cshtml")
[*]</tr>
[*]<tr>
[*]@RenderPage("~/Areas/Products/Views/Products/SetManagementMethods/_StoryTreeType1.cshtml",Product.StoryTreeTypeValues)
[*]</tr>
[*]</table>
<tableclass="noborder"><tr>@RenderPage("~/Areas/Products/Views/Products/SetManagementMethods/_StoryTreeType.cshtml")</tr><tr>@RenderPage("~/Areas/Products/Views/Products/SetManagementMethods/_StoryTreeType1.cshtml",Product.StoryTreeTypeValues)</tr></table>上面的_StoryTreeType1.cshtml是拷贝出来的,将显现在本来页面的上面,如许能够修正的同时能够察看新旧代码及其效果。
2.一点点把StoryTreeType1中的StoryTreeType的影子抹失落
所谓影子,就是间接写着“StoryTreetype”而非一个变量的中央。固然,每抹失落一个,就要多传进一个参数。这里用的是PageData[]参数(MVC3新呈现的)。
注重抹一点测试一下,碰到成绩越早越好。
最初View的外部酿成(注重完整看不就任何和StoryTreeType相干的陈迹了):
[*]@foreach(varcurrentConfiginPageData)
[*]{
[*]<tdstyle="border:none;">
[*]<divclass="help-sample">
[*]<table>
[*]<tr>
[*]<tdstyle="border:none;width:500px;">
[*]@MFCUI.Image("",PageData)<b>@PageData[(int)currentConfig]</b>
[*]@if(PageData==currentConfig)
[*]{
[*]<b>[以后设置]</b>
[*]}
[*]else
[*]{
[*]@MFCUI.Link("[启用]","/MFC/Configs/AjaxSet?key="+PageData+"&value="+(int)currentConfig+"&user=$"+Model.ID,returnTo:this)
[*]@:
[*]}
[*]<table>
[*]<tr>
[*]<tdstyle="border:none;width:200px;">
[*]@RenderPage(PageData)
[*]</td>
[*]<tdstyle="border:none;">
[*]@MFCUI.Image("",Page+"_"+currentConfig+".png")<br/><br/>
[*]</td>
[*]</tr>
[*]</table>
[*]</td>
[*]</tr>
[*]</table>
[*]</div>
[*]</td>
[*]}
@foreach(varcurrentConfiginPageData){<tdstyle="border:none;"><divclass="help-sample"><table><tr><tdstyle="border:none;width:500px;">@MFCUI.Image("",PageData)<b>@PageData[(int)currentConfig]</b>@if(PageData==currentConfig){<b>[以后设置]</b>}else{@MFCUI.Link("[启用]","/MFC/Configs/AjaxSet?key="+PageData+"&value="+(int)currentConfig+"&user=$"+Model.ID,returnTo:this)@:}<table><tr><tdstyle="border:none;width:200px;">@RenderPage(PageData)</td><tdstyle="border:none;">@MFCUI.Image("",Page+"_"+currentConfig+".png")<br/><br/></td></tr></table></td></tr></table></div></td>}而接口也酿成:
[*]<tr>
[*]@RenderPage("~/Areas/Products/Views/Products/SetManagementMethods/_StoryTreeType.cshtml")
[*]</tr>
[*]<tr>
[*]@RenderPage("~/Areas/Products/Views/Products/SetManagementMethods/_StoryTreeType1.cshtml",
[*]Product.StoryTreeTypeValues,"/Products/StoryTree/Index16.png",Product.StoryTreeTypeTexts,Model.StoryTreeType,Product.StoryTreeTypeKey,
[*]"~/Areas/DLC/Views/Products/ManagementMethod/StoryTreeType/_"+Model.StoryTreeType+".cshtml",
[*]"/Products/Products/ManagementMethods/")
[*]</tr>
<tr>@RenderPage("~/Areas/Products/Views/Products/SetManagementMethods/_StoryTreeType.cshtml")</tr><tr>@RenderPage("~/Areas/Products/Views/Products/SetManagementMethods/_StoryTreeType1.cshtml",Product.StoryTreeTypeValues,"/Products/StoryTree/Index16.png",Product.StoryTreeTypeTexts,Model.StoryTreeType,Product.StoryTreeTypeKey,"~/Areas/DLC/Views/Products/ManagementMethod/StoryTreeType/_"+Model.StoryTreeType+".cshtml","/Products/Products/ManagementMethods/")</tr>注重看上面“第二疆场”呈现了良多输出参数。
从表面看,高低两个View的显现效果完整不异(就不贴图了)。
第六步:到场对StatusList的处置
删除第一个tr的代码,拷贝出来一个处置StatusListType的tr,并慢慢修正使之能够事情:
[*]<tableclass="noborder">
[*]<tr>
[*]@RenderPage("~/Areas/Products/Views/Products/SetManagementMethod/_StoryTreeType1.cshtml",
[*]Product.StoryTreeTypeValues,"/Products/StoryTree/Index16.png",Product.StoryTreeTypeTexts,Model.StoryTreeType,Product.StoryTreeTypeKey,
[*]"~/Areas/DLC/Views/Products/ManagementMethod/StoryTreeType/",
[*]"/Products/Products/ManagementMethod/StoryTreeType/")
[*]</tr>
[*]<tr>
[*]@RenderPage("~/Areas/Products/Views/Products/SetManagementMethod/_StoryTreeType1.cshtml",
[*]Product.StatusListTypeValues,"/MFC/Statuses/Index16.png",Product.StatusListTypeTexts,Model.StatusListType,Product.StatusListTypeKey,
[*]"~/Areas/DLC/Views/Products/ManagementMethod/StatusListType/",
[*]"/Products/Products/ManagementMethod/StatusListType/")
[*]</tr>
[*]</table>
<tableclass="noborder"><tr>@RenderPage("~/Areas/Products/Views/Products/SetManagementMethod/_StoryTreeType1.cshtml",Product.StoryTreeTypeValues,"/Products/StoryTree/Index16.png",Product.StoryTreeTypeTexts,Model.StoryTreeType,Product.StoryTreeTypeKey,"~/Areas/DLC/Views/Products/ManagementMethod/StoryTreeType/","/Products/Products/ManagementMethod/StoryTreeType/")</tr><tr>@RenderPage("~/Areas/Products/Views/Products/SetManagementMethod/_StoryTreeType1.cshtml",Product.StatusListTypeValues,"/MFC/Statuses/Index16.png",Product.StatusListTypeTexts,Model.StatusListType,Product.StatusListTypeKey,"~/Areas/DLC/Views/Products/ManagementMethod/StatusListType/","/Products/Products/ManagementMethod/StatusListType/")</tr></table>有几个小技能:
1.修正过程当中,应当修正一个参数就检察一下是不是还事情。
2.优先修正那些不太会招致毛病的数据,好比能够先修正"/MFC/Statuses/Index16.png",Product.StatusListTypeTexts这两个参数,由于他们是笔墨,基础上不会招致毛病。
看看最初了局(由于短少两个图片,以是屏幕显现有成绩):
后续及总结
后续
做完这些,_StoryTreeType1.cshtml这个文件名已不当了,由于它能够1行代码完成任何体系设置(包括一个题目,多少可选项,一组形貌,一张图片),以是下一步必要修正它的名字,而且放到符合的中央。
不外就我们本人的习气而言,我们会先修改名字,然后就放在本来利用它的中央。直到下一次真正被从头利用,再商议放在甚么中央符合。
这句话的官方说法叫做“Useitbeforereusingit“,假如它如今就管这四个界面,就让它好好管着,等往后再说。
总结
全部历程包含写作本博客,约莫耗时2小时。
大概有人会问:不外就是4个页面嘛,就是拷贝粘贴,也用不了1个小时啊,为何要这么费力?
有这么几个缘故原由:
1.将来我们约莫会有20多个如许的设置页面,按下面先容的封装,每天生一页只必要在View中增加一行代码。
2.因为我们还没有美术职员,以是将来大概会修改页面效果,而这些页面都必要坚持不异的作风。
3.将来手艺上大概也会做一些修改,好比谁人Config,这些修改都不但愿往修正良多代码。
实在,全部火星人的产物,就是在这类积木代码中发生的,有良多意想不到的中央都是只需1~2行代码就可以挪用出来(故事树、构造布局图、燃尽图、一切菜单(每一个菜单都是提早加载的)……)
这类习气一旦养成了,代码就会愈来愈简练,而编写历程也愈来愈复杂。
有专家说:net网页编程不是跨平台,net网页编程就是平台,这很好的定义了net网页编程的特点。有了net网页编程,你只需要等待net网页编程平台在新平台上移植。这还不错吧!只是,net网页编程不是一个平台,而是多个平台。你需要在这个net网页编程平台移植到另一个net网页编程平台。 网页从开始简单的hmtl到复杂的服务语言,走过了10多个年头,各种技术层出不穷,单个的主流技术也在不断翻新的版本,现在分析下各种语言的区别、优势、劣势、开发注意事项! 众所周知,Windows以易用而出名,也因此占据不少的服务器市场。 我觉得什么语言,精通就好,你要做的就是比其他80%的人都厉害,你就能得到只有20%的人才能得到的高薪。 网页从开始简单的hmtl到复杂的服务语言,走过了10多个年头,各种技术层出不穷,单个的主流技术也在不断翻新的版本,现在分析下各种语言的区别、优势、劣势、开发注意事项! 由于JSP/Servlet都是基于Java的,所以它们也有Java语言的最大优点——平台无关性,也就是所谓的“一次编写,随处运行(WORA–WriteOnce,RunAnywhere)”。除了这个优点,JSP/Servlet的效率以及安全性也是相当惊人的。 ASP.net的服务器,要求安装一个.net环境,当然我这里指的是windows系统,顺便点一下,.net只能放在windows环境里来运行。Asp.net1.1的就装Framework1.1,Asp.net2.0的就装Framework2.0。 由于JSP/Servlet都是基于Java的,所以它们也有Java语言的最大优点——平台无关性,也就是所谓的“一次编写,随处运行(WORA–WriteOnce,RunAnywhere)”。除了这个优点,JSP/Servlet的效率以及安全性也是相当惊人的。 当然我们在选择Asp.net主机是,除了要考虑服务提供商在版本是否是实时更新以外,机房的环境和配置也是非常重要的,通常选择骨干网的机房,在速度和稳定性上会非常有保证。 网页从开始简单的hmtl到复杂的服务语言,走过了10多个年头,各种技术层出不穷,单个的主流技术也在不断翻新的版本,现在分析下各种语言的区别、优势、劣势、开发注意事项! 但是java靠开源打出的一片天地,特别是在微软的垄断下能打开今天的局面还是有它的生命力的。
页:
[1]