前言:上篇介绍了下ko增删改查的封装,确实节省了大量的js代码 。博主是一个喜欢偷懒的人,总觉得这些基础的增删改查效果 能不能通过一个什么工具直接生成 页面 效果 ,啥代码 都不用写了,那该多爽。于是研究了下T4的语法,虽然没有完全掌握,但是算是有了一个大致的了解。于是乎有了今天的这篇文章 :通过T4模板快速 生成 页面 。
KnockoutJS系列文章 :
解决方 案(三)两个viewmode l搞定增删改查
一、T4的使用介绍
我们知道,MVC里面在添加 视图的时候可以自动 生成 增删改查的页面 效果 ,那是因为MVC为我们内置了基础增删改查的模板,这些模板的语法就是使用T4,那么这些模板在哪里呢?找了下相关文章 ,发现MVC4及以下的版本模板位置和MVC5及以上模板的位置有很大的不同。
•MVC4及以下版本的模板位置:VS的安装目录+\ItemTemplates\CSharp\Web\MVC 2\CodeTemplates。比如博主的D:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ItemTemplates\CSharp\Web\MVC 4\CodeTemplates。
找到cshtml对应的模板,里面就有相应的增删改查的tt文件
•MVC5及以上版本的模板位置:直接给出博主的模板位置D:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Web\Mvc\Scaffolding\Templates
知道了这个,那么接下来就是改造模板,添加 自己的生成 内容 了。可以直接将List和Edit模板拷贝到过来自行改造,但是最后想了想,还是别动MVC内置的东西了,我们自己来建自己的模板不是更好。
在当前Web项目的根目录下面新建一个文件 夹,命名为CodeTemplates,然后将MVC模板里面的MvcControllerEmpty和MvcView两个模板文件 夹拷贝到CodeTemplates文件 夹下面,去掉它里面的原始模板,然后新建几个自己的模板,如下图:
这样我们在添加 新的控制器和新建视图的时候就可以看到我们自定义 的模板了:
二、T4代码 介绍
上面介绍了如何新建自己的模板,模板建好之后就要开始往里面塞相应的内容 了,如果T4的语法展开了说,那一篇是说不完的,有兴趣的园友可以去园子里找找,文章 还是挺多的。这里主要还是来看看几个模板内容 。还有一点需要说明下,貌似从MVC5之后,T4的模板文件 后缀全部改成了t4,而之前的模板一直是tt结尾的,没有细究它们语法的区别,估计应该差别不大。
1、Controller.cs.t4
为什么要重写这个空的控制器模板呢?博主觉得增删改查的好多方法 都需要手动去写好麻烦,写一个模板直接生成 可以省事很多。来看看模板里面的实现代码 :
<#@ output extension="cs" #>
<#@ parameter type="System.String" name="ControllerName" #>
<#@ parameter type="System.String" name="ControllerRootName" #>
<#@ parameter type="System.String" name="Namespace" #>
<#@ parameter type="System.String" name="AreaName" #>
<#
var index = ControllerName.LastIndexOf("Controller");
var ModelName = ControllerName.Substring(0,index);
#>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TestKO.Models;
namespace <#= Namespace #>
{
public class <#= ControllerName #> : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Edit(<#= ModelName #> model)
{
return View(model);
}
[HttpGet]
public JsonResult Get(int limit,int offset)
{
return Json(new { },JsonRequestBehavior.AllowGet);
}
//新增实体
[HttpPost]
public JsonResult Add(<#= ModelName #> oData)
{
<#= ModelName #>Model.Add(oData);
return Json(new { },JsonRequestBehavior.AllowGet);
}
//更新实体
[HttpPost]
public JsonResult Update(<#= ModelName #> oData)
{
<#= ModelName #>Model.Update(oData);
return Json(new { },JsonRequestBehavior.AllowGet);
}
//
删除 实体
[HttpPost]
public JsonResult Delete(List<<#= ModelName #>> oData)
{
<#= ModelName #>Model.Delete(oData);
return Json(new { },JsonRequestBehavior.AllowGet);
}
}
}
这个内容 不难理解,直接查看生成 的控制器代码 :
删除实体
[HttpPost]
public JsonResult Delete(List oData)
{
UserModel.Delete(oData);
return Json(new { },JsonRequestBehavior.AllowGet);
}
}
}
2、KoIndex.cs.t4
这个模板主要用于生成 列表页 面,大致代码 如下:
<#@ output extension=".cshtml" #>
<#@ include file="Imports.include.t4" #>
<#
// The following chained if-statement outputs the file header code and markup for a partial view,a view using a layout page,or a regular view.
if(IsPartialView) {
#>
<#
} else if(IsLayoutPageSelected) {
#>
@{
ViewBag.Title = "<#= ViewName#>";
<#
if (!String.IsNullOrEmpty(LayoutPageFile)) {
#>
Layout = "<#= LayoutPageFile#>";
<#
}
#>
}
<#
} else {
#>
@{
Layout = null;
}
<#= ViewName #>
<#
PushIndent(" ");
}
#>
Box="true">
<#
IEnumerable properties = ModelMeta data.Properties;
foreach (PropertyMeta data property in properties) {
if (property.Scaffold && !property.IsPrimaryKey && !property.IsForeignKey) {
#>
<#
}
}#>
<#
if(!IsPartialView && !IsLayoutPageSelected) {
ClearIndent();
#>
<#
}
#>
<#@ include file="ModelMetadataFunctions.cs.include.t4" #>
添加 一个视图Index,然后选择这个模板
得到的页面 内容
我们将上篇说的viewmode l搬到页面 上面来了,这样每次就不用从controller里面传过来了。稍微改一下表格的列名,页面 就可以跑起来了。
这里有待优化的几点:
(1)查询 条件没有生成 ,如果将T4的语法研究深一点,可以在需要查询 的字段上面添加 特性标识哪些字段需要查询 ,然后自动 生成 对应的查询 条件。
(2)表格的列名似乎也可以通过属性 的字段特性来生成 。这点和第一点类似,都需要研究T4的语法。
3、KoEdit.cs.t4
第三个模板页就是编辑的模板了,它的大致代码 如下:
<#@ output extension=".cshtml" #>
<#@ include file="Imports.include.t4" #>
@model <#= ViewDataTypeName #>
<#
// "form-control" attribute is only supported for all EditorFor() in System.Web.Mvc 5.1.0.0 or later versions,except for checkbox,which uses a div in Bootstrap
string boolType = "System.Boolean";
Version requiredMvcVersion = new Version("5.1.0.0");
bool isControlHtmlAttributesSupported = MvcVersion >=
required MvcVersion;
// The following chained if-statement outputs the file header code and markup for a partial view,or a regular view.
if(IsPartialView) {
#>
<#
} else if(IsLayoutPageSelected) {
#>
@{
ViewBag.Title = "<#= ViewName#>";
<#
if (!String.IsNullOrEmpty(LayoutPageFile)) {
#>
Layout = "<#= LayoutPageFile#>";
<#
}
#>
}
<#= ViewName#>
<#
} else {
#>
@{
Layout = null;
}
<#= ViewName #>
<#
PushIndent(" ");
}
#>
<#
if (ReferenceScriptLibraries) {
#>
<#
if (!IsLayoutPageSelected && IsBundleConfigPresent) {
#>
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryval")
<#
}
#>
<#
else if (!IsLayoutPageSelected) {
#>
<#
if(IsLayoutPageSelected && ReferenceScriptLibraries && IsBundleConfigPresent) {
#>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
<#
}
#>
<#
else if(IsLayoutPageSelected && ReferenceScriptLibraries) {
#>
Edit.cshtml
当然,代码 也需要做稍许修改 。通过添加 自定义 的模板页,只要后台 对应的实体模型建好了,在前端只需要新建两个自定义 视图,一个简单的增删改查即可完成,不用写一句js代码 。
三、select组件的绑定
上面介绍了下T4封装增删改查的语法,页面 所有的组件基本都是文本框,然而,在实际项目中,很多的查询 和编辑页面 都会存在下拉框的展示,对于下拉框,我们该如何处理呢?不卖关子了,直接给出解决方 案吧,比如编辑页面 我们可以在后台 将下拉框的数据源放在实体里面。
用户 的实体
然后编辑页面
然后前端绑定即可。