JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(四):自定义T4模板快速生成页面
前言:上篇介绍了下ko增删改查的封装,确实节省了大量的js代码。博主是一个喜欢偷懒的人,总觉得这些基础的增删改查效果能不能通过一个什么工具直接生成页面效果,啥代码都不用写了,那该多爽。于是研究了下T4的语法,虽然没有完全掌握,但是算是有了一个大致的了解,给需要自定义模板的园友们提供一个参考。于是乎有了今天的这篇文章:通过T4模板快速生成页面。
KnockoutJS系列文章:
- JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(一)
- JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(二)
- JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(三):两个Viewmodel搞定增删改查
- JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(四):自定义T4模板快速生成页面
本文原创地址:http://www.cnblogs.com/landeanfen/p/5667022.html
一、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
为什么要重写这个空的控制器模板呢?博主觉得增删改查的好多方法都需要手动去写好麻烦,写一个模板直接生成可以省事很多。来看看模板里面的实现代码:
<#@ template language="C#" HostSpecific="True" #>
<#@ 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(, 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);
}
}
}
这个内容不难理解,直接查看生成的控制器代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TestKO.Models; namespace TestKO.Controllers
{
public class UserController : Controller
{
public ActionResult Index()
{
return View();
} public ActionResult Edit(User model)
{
return View(model);
} [HttpGet]
public JsonResult Get(int limit, int offset)
{
return Json(new { }, JsonRequestBehavior.AllowGet);
} //新增实体
[HttpPost]
public JsonResult Add(User oData)
{
UserModel.Add(oData);
return Json(new { }, JsonRequestBehavior.AllowGet);
} //更新实体
[HttpPost]
public JsonResult Update(User oData)
{
UserModel.Update(oData);
return Json(new { }, JsonRequestBehavior.AllowGet);
} //删除实体
[HttpPost]
public JsonResult Delete(List<User> oData)
{
UserModel.Delete(oData);
return Json(new { }, JsonRequestBehavior.AllowGet);
}
}
}
2、KoIndex.cs.t4
这个模板主要用于生成列表页面,大致代码如下:
<#@ template language="C#" HostSpecific="True" #>
<#@ 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;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title><#= ViewName #></title>
<link href="~/Content/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<link href="~/Content/bootstrap-table/bootstrap-table.min.css" rel="stylesheet" /> <script src="~/scripts/jquery-1.9.1.min.js"></script>
<script src="~/Content/bootstrap/js/bootstrap.min.js"></script>
<script src="~/Content/bootstrap-table/bootstrap-table.min.js"></script>
<script src="~/Content/bootstrap-table/locale/bootstrap-table-zh-CN.js"></script> <script src="~/scripts/knockout/knockout-3.4.0.min.js"></script>
<script src="~/scripts/knockout/extensions/knockout.mapping-latest.js"></script>
<script src="~/scripts/extensions/knockout.index.js"></script>
<script src="~/scripts/extensions/knockout.bootstraptable.js"></script>
<script type="text/javascript">
$(function () {
var viewModel = {
bindId: "div_index",
tableParams :
{
url : "/<#=ViewDataTypeShortName#>/Get",
pageSize : ,
},
urls :
{
del : "/<#=ViewDataTypeShortName#>/Delete",
edit : "/<#=ViewDataTypeShortName#>/Edit",
add : "/<#=ViewDataTypeShortName#>/Edit",
},
queryCondition :
{ }
};
ko.bindingViewModel(viewModel);
});
</script>
</head>
<body>
<#
PushIndent(" ");
}
#>
<div id="toolbar">
<button data-bind="click:addClick" type="button" class="btn btn-default">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>新增
</button>
<button data-bind="click:editClick" type="button" class="btn btn-default">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>修改
</button>
<button data-bind="click:deleteClick" type="button" class="btn btn-default">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>删除
</button>
</div>
<table data-bind="bootstrapTable:bootstrapTable">
<thead>
<tr>
<th data-checkbox="true"></th>
<#
IEnumerable<PropertyMetadata> properties = ModelMetadata.Properties;
foreach (PropertyMetadata property in properties) {
if (property.Scaffold && !property.IsPrimaryKey && !property.IsForeignKey) {
#>
<th data-field="<#= GetValueExpression(property) #>"><#= GetValueExpression(property) #></th>
<#
}
}#>
</tr>
</thead>
</table>
<#
// The following code closes the tag used in the case of a view using a layout page and the body and html tags in the case of a regular view page
#>
<#
if(!IsPartialView && !IsLayoutPageSelected) {
ClearIndent();
#>
</body>
</html>
<#
}
#>
<#@ include file="ModelMetadataFunctions.cs.include.t4" #>
添加一个视图Index,然后选择这个模板
得到的页面内容
@{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<link href="~/Content/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<link href="~/Content/bootstrap-table/bootstrap-table.min.css" rel="stylesheet" /> <script src="~/scripts/jquery-1.9.1.min.js"></script>
<script src="~/Content/bootstrap/js/bootstrap.min.js"></script>
<script src="~/Content/bootstrap-table/bootstrap-table.min.js"></script>
<script src="~/Content/bootstrap-table/locale/bootstrap-table-zh-CN.js"></script> <script src="~/scripts/knockout/knockout-3.4.0.min.js"></script>
<script src="~/scripts/knockout/extensions/knockout.mapping-latest.js"></script>
<script src="~/scripts/extensions/knockout.index.js"></script>
<script src="~/scripts/extensions/knockout.bootstraptable.js"></script>
<script type="text/javascript">
$(function () {
var viewModel = {
bindId: "div_index",
tableParams :
{
url : "/User/Get",
pageSize : 2,
},
urls :
{
del : "/User/Delete",
edit : "/User/Edit",
add : "/User/Edit",
},
queryCondition :
{ }
};
ko.bindingViewModel(viewModel);
});
</script>
</head>
<body>
<div id="toolbar">
<button data-bind="click:addClick" type="button" class="btn btn-default">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>新增
</button>
<button data-bind="click:editClick" type="button" class="btn btn-default">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>修改
</button>
<button data-bind="click:deleteClick" type="button" class="btn btn-default">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>删除
</button>
</div>
<table data-bind="bootstrapTable:bootstrapTable">
<thead>
<tr>
<th data-checkbox="true"></th>
<th data-field="Name">Name</th>
<th data-field="FullName">FullName</th>
<th data-field="Age">Age</th>
<th data-field="Des">Des</th>
<th data-field="Createtime">Createtime</th>
<th data-field="strCreatetime">strCreatetime</th>
</tr>
</thead>
</table>
</body>
</html>
Index.cshtml
我们将上篇说的viewmodel搬到页面上面来了,这样每次就不用从controller里面传过来了。稍微改一下表格的列名,页面就可以跑起来了。
这里有待优化的几点:
(1)查询条件没有生成,如果将T4的语法研究深一点,可以在需要查询的字段上面添加特性标识哪些字段需要查询,然后自动生成对应的查询条件。
(2)表格的列名似乎也可以通过属性的字段特性来生成。这点和第一点类似,都需要研究T4的语法。
3、KoEdit.cs.t4
第三个模板页就是编辑的模板了,它的大致代码如下:
<#@ template language="C#" HostSpecific="True" #>
<#@ 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 >= requiredMvcVersion;
// 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#>";
<#
}
#>
} <h2><#= ViewName#></h2> <#
} else {
#> @{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title><#= ViewName #></title>
</head>
<body>
<#
PushIndent(" ");
}
#>
<#
if (ReferenceScriptLibraries) {
#>
<#
if (!IsLayoutPageSelected && IsBundleConfigPresent) {
#>
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryval") <#
}
#>
<#
else if (!IsLayoutPageSelected) {
#>
<script src="~/Scripts/jquery-<#= JQueryVersion #>.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script> <#
}
#> <#
}
#>
<form id="formEdit" class="form-horizontal">
@Html.HiddenFor(model => model.Id)
<div class="modal-body">
<#
IEnumerable<PropertyMetadata> properties = ModelMetadata.Properties;
foreach (PropertyMetadata property in properties) {
if (property.Scaffold && !property.IsPrimaryKey && !property.IsForeignKey) {
#>
<div class="form-group">
@Html.LabelFor(model => model.<#= GetValueExpression(property) #>, "<#= GetValueExpression(property) #>", new { @class = "control-label col-xs-2" })
<div class="col-xs-10">
@Html.TextBoxFor(model => model.<#= GetValueExpression(property) #>, new { @class = "form-control", data_bind = "value:editModel.<#= GetValueExpression(property) #>" })
</div>
</div>
<#
}
}
#>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span>关闭</button>
<button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>保存</button>
</div>
</form>
<#
var index = ViewDataTypeName.LastIndexOf(".");
var ModelName = ViewDataTypeName.Substring(index+, ViewDataTypeName.Length-index-);
#>
<script src="~/Scripts/extensions/knockout.edit.js"></script>
<script type="text/javascript">
$(function () {
var model = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model));
var viewModel = {
formId: "formEdit",
editModel : model,
urls :
{
submit : model.id == ? "/<#= ModelName #>/Add" : "/<#= ModelName #>/Update"
},
validator:{
fields: {
Name: {
validators: {
notEmpty: {
message: '名称不能为空!'
}
}
}
}
}
};
ko.bindingEditViewModel(viewModel);
});
</script>
<#
if(IsLayoutPageSelected && ReferenceScriptLibraries && IsBundleConfigPresent) {
#> @section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
<#
}
#>
<#
else if(IsLayoutPageSelected && ReferenceScriptLibraries) {
#> <script src="~/Scripts/jquery-<#= JQueryVersion #>.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<#
}
#>
<#
// The following code closes the tag used in the case of a view using a layout page and the body and html tags in the case of a regular view page
#>
<#
if(!IsPartialView && !IsLayoutPageSelected) {
ClearIndent();
#>
</body>
</html>
<#
}
#>
<#@ include file="ModelMetadataFunctions.cs.include.t4" #>
生成的代码:
@model TestKO.Models.User <form id="formEdit" class="form-horizontal">
@Html.HiddenFor(model => model.Id)
<div class="modal-body">
<div class="form-group">
@Html.LabelFor(model => model.Name, "Name", new { @class = "control-label col-xs-2" })
<div class="col-xs-10">
@Html.TextBoxFor(model => model.Name, new { @class = "form-control", data_bind = "value:editModel.Name" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.FullName, "FullName", new { @class = "control-label col-xs-2" })
<div class="col-xs-10">
@Html.TextBoxFor(model => model.FullName, new { @class = "form-control", data_bind = "value:editModel.FullName" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Age, "Age", new { @class = "control-label col-xs-2" })
<div class="col-xs-10">
@Html.TextBoxFor(model => model.Age, new { @class = "form-control", data_bind = "value:editModel.Age" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Des, "Des", new { @class = "control-label col-xs-2" })
<div class="col-xs-10">
@Html.TextBoxFor(model => model.Des, new { @class = "form-control", data_bind = "value:editModel.Des" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Createtime, "Createtime", new { @class = "control-label col-xs-2" })
<div class="col-xs-10">
@Html.TextBoxFor(model => model.Createtime, new { @class = "form-control", data_bind = "value:editModel.Createtime" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.strCreatetime, "strCreatetime", new { @class = "control-label col-xs-2" })
<div class="col-xs-10">
@Html.TextBoxFor(model => model.strCreatetime, new { @class = "form-control", data_bind = "value:editModel.strCreatetime" })
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span>关闭</button>
<button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>保存</button>
</div>
</form>
<script src="~/Scripts/extensions/knockout.edit.js"></script>
<script type="text/javascript">
$(function () {
var model = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model));
var viewModel = {
formId: "formEdit",
editModel : model,
urls :
{
submit : model.id == 0 ? "/User/Add" : "/User/Update"
},
validator:{
fields: {
Name: {
validators: {
notEmpty: {
message: '名称不能为空!'
}
}
}
}
}
};
ko.bindingEditViewModel(viewModel);
});
</script>
Edit.cshtml
当然,代码也需要做稍许修改。通过添加自定义的模板页,只要后台对应的实体模型建好了,在前端只需要新建两个自定义视图,一个简单的增删改查即可完成,不用写一句js代码。
三、select组件的绑定
上面介绍了下T4封装增删改查的语法,页面所有的组件基本都是文本框,然而,在实际项目中,很多的查询和编辑页面都会存在下拉框的展示,对于下拉框,我们该如何处理呢?不卖关子了,直接给出解决方案吧,比如编辑页面我们可以在后台将下拉框的数据源放在实体里面。
用户的实体
[DataContract]
public class User
{
[DataMember]
public int id { get; set; } [DataMember]
public string Name { get; set; } [DataMember]
public string FullName { get; set; } [DataMember]
public int Age { get; set; } [DataMember]
public string Des { get; set; } [DataMember]
public DateTime Createtime { get; set; } [DataMember]
public string strCreatetime { get; set; } [DataMember]
public string DepartmentId { get; set; } [DataMember]
public object Departments { get; set; }
}
然后编辑页面
public ActionResult Edit(User model)
{
model.Departments = DepartmentModel.GetData();
return View(model);
}
然后前端绑定即可。
<div class="form-group">
<label for="txt_des">所属部门</label>
<select id="sel_dept" class="form-control" data-bind="options: editModel.Departments,
optionsText: 'Name',
optionsValue: 'Id',
value:editModel.DepartmentId"></select>
</div>
JS代码不用做任何修改,新增和编辑的时候部门字段就能自动添加到viewmodel里面去。
当然,我们很多项目使用的下拉框都不是单纯的select,因为单纯的select样式实在是难看,于是乎出了很多的select组件,比如博主之前分享的select2、MultiSelect等等。当使用这些组件去初始化select时,审核元素你会发现,这个时候界面上的下拉框已经不是单纯的select标签了,而是由组件自定义的很多其他标签组成。我们就以select2组件为例来看看直接按照上面的这样初始化是否可行。
我们将编辑页面初始化的js代码增加最后一句:
<script type="text/javascript">
$(function () {
var model = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model));
var viewModel = {
formId: "formEdit",
editModel : model,
urls :
{
submit : model.id == 0 ? "/User/Add" : "/User/Update"
},
validator:{
fields: {
Name: {
validators: {
notEmpty: {
message: '名称不能为空!'
}
}
}
}
}
};
ko.bindingEditViewModel(viewModel); $("#sel_dept").select2({});
});
</script>
通过新增和编辑发现,这样确实可行!分析原因,虽然初始化成select2组件之后,页面的html发生了变化,但是组件最终还是会将选中值呈现在原始的select控件上面。不知道除了select2,其他select初始化组件会不会这样,待验证。但是这里有一点需要说明下,在初始化select2之前,下拉框的options必须先绑定值,也就是说,组件的初始化必须要放在ko.applyBinding()之后。
四、总结
至此,ko结合bootstrapTable的模板生成以及select控件的使用基本可用,当然,还有待完善。后面如果有时间,博主会整理下其他前端组件和ko的联合使用,比如我们最常见的日期控件。如果你觉得本文对你有帮助,欢迎推荐。
本文原创出处:http://www.cnblogs.com/landeanfen/
欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利
JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(四):自定义T4模板快速生成页面的更多相关文章
- JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(一)
前言:出于某种原因,需要学习下Knockout.js,这个组件很早前听说过,但一直没尝试使用,这两天学习了下,觉得它真心不错,双向绑定的机制简直太爽了.今天打算结合bootstrapTable和Kno ...
- JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(三):两个Viewmodel搞定增删改查
前言:之前博主分享过knockoutJS和BootstrapTable的一些基础用法,都是写基础应用,根本谈不上封装,仅仅是避免了html控件的取值和赋值,远远没有将MVVM的精妙展现出来.最近项目打 ...
- JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(二)
前言:上篇 JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(一) 介绍了下knockout.js的一些基础用法,由于篇幅的关系,所以只能分成两篇,望见谅!昨天就 ...
- BootstrapTable+KnockoutJS实现增删改查解决方案
BootstrapTable+KnockoutJS实现增删改查解决方案 前言:上篇介绍了下ko增删改查的封装,确实节省了大量的js代码.博主是一个喜欢偷懒的人,总觉得这些基础的增删改查效果能不能通过一 ...
- JQuery Easyui/TopJUI 用JS创建数据表格并实现增删改查功能
JQuery Easyui/TopJUI 用JS创建数据表格并实现增删改查功能 html <table id="productDg"></table> &l ...
- django中的forms组件(权限信息校验,增删改查)
1.用处 1.用户请求数据验证 2.自动生成错误信息 3.打包用户提交的正确信息 4.如果其中有一个错误了,其他的正确,则保留上次输入的内容 5.自动创建input标签并可以设置样式 6.基于form ...
- hibernate系列笔记(1)---Hibernate增删改查
Hibernate增删改查 1.首先我们要知道什么是Hibernate Hibernate是一个轻量级的ORMapping对象.主要用来实现Java和数据库表之间的映射,除此之外还提供数据查询和数据获 ...
- JS组件系列——BootstrapTable 行内编辑解决方案:x-editable
前言:之前介绍bootstrapTable组件的时候有提到它的行内编辑功能,只不过为了展示功能,将此一笔带过了,罪过罪过!最近项目里面还是打算将行内编辑用起来,于是再次研究了下x-editable组件 ...
- [转]JS组件系列——BootstrapTable 行内编辑解决方案:x-editable
本文转自:http://www.cnblogs.com/landeanfen/p/5821192.html 阅读目录 一.x-editable组件介绍 二.bootstrapTable行内编辑初始方案 ...
随机推荐
- Linux主机上实现树莓派的交叉编译及文件传输,远程登陆
0.环境 Linux主机OS:Ubuntu14.04 64位,运行在wmware workstation 10虚拟机 树莓派版本:raspberry pi 2 B型. 树莓派OS:官网下的的raspb ...
- const 与 readonly知多少
原文地址: http://www.cnblogs.com/royenhome/archive/2010/05/22/1741592.html 尽管你写了很多年的C#的代码,但是可能当别人问到你cons ...
- .NET DateTime类型变量作为参数时设置默认值
一个小的 Tips. .NET 中函数参数的默认值需要是编译时常量.如果参数是引用类型,可以设置Null,如果是值类型,可以设置相应的编译时常量,如整型可以用整数,但对于DateTime(结构体,值类 ...
- 关于Linux下转换oracle字符集
前阵子给以同事导oracle数据库,但是发现导入后数据都是乱码,下面是自己解决这个问题的一些小整理. 比如: #su oralce $export ORACLE_SID=orcl $export OR ...
- 应用SqlGeometry无法加载sqlserverspatial.dll
最近需要完成一个API,通过用户上传的经纬度判断用户的所在县市省,数据量相对不是很大所以把相关数据全部扔到了内存里知行,主要用到了SqlGeometry, 代码写完后运行本地没问题,扔到服务器上开始报 ...
- javaScript的内置对象
javaScript 有11种内置对象: Array . String .Date .Math . Boolean .Number . Function .Global .Error . RegExp ...
- 如果把带有html的标记的字符串从服务端传到页面上,需要对其进行编码。Ajax.JavaScriptStringEncode()
controller: StringBuilder s = new StringBuilder(); string a = "<script>alert('我StringBuil ...
- javascript代码 调试方法
你的代码可能包含语法错误,逻辑错误,如果没有调试工具,这些错误比较难于发现. 通常,如果 JavaScript 出现错误,是不会有提示信息,这样你就无法找到代码错误的位置. 在程序代码中寻找错误叫做代 ...
- Titanium.UI.createAlertDialog
学习TI 记录一下 1.确认对话框 Js代码 var a = Titanium.UI.createAlertDialog({ title:'添加人员信息', message:"人员添加成功& ...
- swift-元组
元组: 将多个相同或者不同类型的值用一个小括号括起来就是一个元组.元组和结构体很像,实际上元组是复合类型.小括号内可以写任意类型,如果不定义类型,可以根据数据自动判断推算出类型 省略了类型 let p ...