欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

BootstrapTable+KnockoutJS自定義T4模板快速生成增刪改查頁(yè)面

 更新時(shí)間:2016年08月01日 15:38:55   作者:懶得安分  
這篇文章主要介紹了BootstrapTable+KnockoutJS自定義T4模板快速生成增刪改查頁(yè)面 的相關(guān)資料,需要的朋友可以參考下

前言:上篇介紹了下ko增刪改查的封裝,確實(shí)節(jié)省了大量的js代碼。博主是一個(gè)喜歡偷懶的人,總覺(jué)得這些基礎(chǔ)的增刪改查效果能不能通過(guò)一個(gè)什么工具直接生成頁(yè)面效果,啥代碼都不用寫(xiě)了,那該多爽。于是研究了下T4的語(yǔ)法,雖然沒(méi)有完全掌握,但是算是有了一個(gè)大致的了解。于是乎有了今天的這篇文章:通過(guò)T4模板快速生成頁(yè)面。

KnockoutJS系列文章:

BootstrapTable與KnockoutJS相結(jié)合實(shí)現(xiàn)增刪改查功能【一】

BootstrapTable與KnockoutJS相結(jié)合實(shí)現(xiàn)增刪改查功能【二】

BootstrapTable+KnockoutJS相結(jié)合實(shí)現(xiàn)增刪改查解決方案(三)兩個(gè)Viewmodel搞定增刪改查

一、T4的使用介紹

我們知道,MVC里面在添加視圖的時(shí)候可以自動(dòng)生成增刪改查的頁(yè)面效果,那是因?yàn)镸VC為我們內(nèi)置了基礎(chǔ)增刪改查的模板,這些模板的語(yǔ)法就是使用T4,那么這些模板在哪里呢?找了下相關(guān)文章,發(fā)現(xiàn)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對(duì)應(yīng)的模板,里面就有相應(yīng)的增刪改查的tt文件

•MVC5及以上版本的模板位置:直接給出博主的模板位置D:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Web\Mvc\Scaffolding\Templates

知道了這個(gè),那么接下來(lái)就是改造模板,添加自己的生成內(nèi)容了??梢灾苯訉ist和Edit模板拷貝到過(guò)來(lái)自行改造,但是最后想了想,還是別動(dòng)MVC內(nèi)置的東西了,我們自己來(lái)建自己的模板不是更好。

在當(dāng)前Web項(xiàng)目的根目錄下面新建一個(gè)文件夾,命名為CodeTemplates,然后將MVC模板里面的MvcControllerEmpty和MvcView兩個(gè)模板文件夾拷貝到CodeTemplates文件夾下面,去掉它里面的原始模板,然后新建幾個(gè)自己的模板,如下圖:

這樣我們?cè)谔砑有碌目刂破骱托陆ㄒ晥D的時(shí)候就可以看到我們自定義的模板了:

二、T4代碼介紹

上面介紹了如何新建自己的模板,模板建好之后就要開(kāi)始往里面塞相應(yīng)的內(nèi)容了,如果T4的語(yǔ)法展開(kāi)了說(shuō),那一篇是說(shuō)不完的,有興趣的園友可以去園子里找找,文章還是挺多的。這里主要還是來(lái)看看幾個(gè)模板內(nèi)容。還有一點(diǎn)需要說(shuō)明下,貌似從MVC5之后,T4的模板文件后綴全部改成了t4,而之前的模板一直是tt結(jié)尾的,沒(méi)有細(xì)究它們語(yǔ)法的區(qū)別,估計(jì)應(yīng)該差別不大。

1、Controller.cs.t4

為什么要重寫(xiě)這個(gè)空的控制器模板呢?博主覺(jué)得增刪改查的好多方法都需要手動(dòng)去寫(xiě)好麻煩,寫(xiě)一個(gè)模板直接生成可以省事很多。來(lái)看看模板里面的實(shí)現(xiàn)代碼:

<#@ 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(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);
}
//新增實(shí)體
[HttpPost]
public JsonResult Add(<#= ModelName #> oData)
{
<#= ModelName #>Model.Add(oData);
return Json(new { }, JsonRequestBehavior.AllowGet);
}
//更新實(shí)體
[HttpPost]
public JsonResult Update(<#= ModelName #> oData)
{
<#= ModelName #>Model.Update(oData);
return Json(new { }, JsonRequestBehavior.AllowGet);
}
//刪除實(shí)體
[HttpPost]
public JsonResult Delete(List<<#= ModelName #>> oData)
{
<#= ModelName #>Model.Delete(oData);
return Json(new { }, JsonRequestBehavior.AllowGet);
}
}
}

這個(gè)內(nèi)容不難理解,直接查看生成的控制器代碼:

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);
}
//新增實(shí)體
[HttpPost]
public JsonResult Add(User oData)
{
UserModel.Add(oData);
return Json(new { }, JsonRequestBehavior.AllowGet);
}
//更新實(shí)體
[HttpPost]
public JsonResult Update(User oData)
{
UserModel.Update(oData);
return Json(new { }, JsonRequestBehavior.AllowGet);
}
//刪除實(shí)體
[HttpPost]
public JsonResult Delete(List<User> oData)
{
UserModel.Delete(oData);
return Json(new { }, JsonRequestBehavior.AllowGet);
}
}
}

2、KoIndex.cs.t4

這個(gè)模板主要用于生成列表頁(yè)面,大致代碼如下:

<#@ 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 : 2,
},
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" #>

添加一個(gè)視圖Index,然后選擇這個(gè)模板

得到的頁(yè)面內(nèi)容

@{
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

我們將上篇說(shuō)的viewmodel搬到頁(yè)面上面來(lái)了,這樣每次就不用從controller里面?zhèn)鬟^(guò)來(lái)了。稍微改一下表格的列名,頁(yè)面就可以跑起來(lái)了。

這里有待優(yōu)化的幾點(diǎn):

(1)查詢條件沒(méi)有生成,如果將T4的語(yǔ)法研究深一點(diǎn),可以在需要查詢的字段上面添加特性標(biāo)識(shí)哪些字段需要查詢,然后自動(dòng)生成對(duì)應(yīng)的查詢條件。

(2)表格的列名似乎也可以通過(guò)屬性的字段特性來(lái)生成。這點(diǎn)和第一點(diǎn)類似,都需要研究T4的語(yǔ)法。

3、KoEdit.cs.t4

第三個(gè)模板頁(yè)就是編輯的模板了,它的大致代碼如下:

<#@ 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>關(guān)閉</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+1, ViewDataTypeName.Length-index-1);
#>
<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 ? "/<#= 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>關(guān)閉</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

當(dāng)然,代碼也需要做稍許修改。通過(guò)添加自定義的模板頁(yè),只要后臺(tái)對(duì)應(yīng)的實(shí)體模型建好了,在前端只需要新建兩個(gè)自定義視圖,一個(gè)簡(jiǎn)單的增刪改查即可完成,不用寫(xiě)一句js代碼。

三、select組件的綁定

上面介紹了下T4封裝增刪改查的語(yǔ)法,頁(yè)面所有的組件基本都是文本框,然而,在實(shí)際項(xiàng)目中,很多的查詢和編輯頁(yè)面都會(huì)存在下拉框的展示,對(duì)于下拉框,我們?cè)撊绾翁幚砟??不賣關(guān)子了,直接給出解決方案吧,比如編輯頁(yè)面我們可以在后臺(tái)將下拉框的數(shù)據(jù)源放在實(shí)體里面。

用戶的實(shí)體

[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; }
}

然后編輯頁(yè)面

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代碼不用做任何修改,新增和編輯的時(shí)候部門字段就能自動(dòng)添加到viewmodel里面去。

當(dāng)然,我們很多項(xiàng)目使用的下拉框都不是單純的select,因?yàn)閱渭兊膕elect樣式實(shí)在是難看,于是乎出了很多的select組件,比如博主之前分享的select2、MultiSelect等等。當(dāng)使用這些組件去初始化select時(shí),審核元素你會(huì)發(fā)現(xiàn),這個(gè)時(shí)候界面上的下拉框已經(jīng)不是單純的select標(biāo)簽了,而是由組件自定義的很多其他標(biāo)簽組成。我們就以select2組件為例來(lái)看看直接按照上面的這樣初始化是否可行。

我們將編輯頁(yè)面初始化的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>

通過(guò)新增和編輯發(fā)現(xiàn),這樣確實(shí)可行!分析原因,雖然初始化成select2組件之后,頁(yè)面的html發(fā)生了變化,但是組件最終還是會(huì)將選中值呈現(xiàn)在原始的select控件上面。不知道除了select2,其他select初始化組件會(huì)不會(huì)這樣,待驗(yàn)證。但是這里有一點(diǎn)需要說(shuō)明下,在初始化select2之前,下拉框的options必須先綁定值,也就是說(shuō),組件的初始化必須要放在ko.applyBinding()之后。

四、總結(jié)

至此,ko結(jié)合bootstrapTable的模板生成以及select控件的使用基本可用,當(dāng)然,還有待完善。后面如果有時(shí)間,博主會(huì)整理下其他前端組件和ko的聯(lián)合使用,比如我們最常見(jiàn)的日期控件。如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • JavaScript實(shí)現(xiàn)數(shù)組隨機(jī)排序的方法

    JavaScript實(shí)現(xiàn)數(shù)組隨機(jī)排序的方法

    這篇文章主要介紹了JavaScript實(shí)現(xiàn)數(shù)組隨機(jī)排序的方法,涉及javascript數(shù)組遍歷與排序的相關(guān)技巧,需要的朋友可以參考下
    2015-06-06
  • 在視頻前插入廣告

    在視頻前插入廣告

    在視頻前插入廣告...
    2006-11-11
  • js實(shí)現(xiàn)簡(jiǎn)單的二級(jí)聯(lián)動(dòng)效果

    js實(shí)現(xiàn)簡(jiǎn)單的二級(jí)聯(lián)動(dòng)效果

    本文主要介紹了js實(shí)現(xiàn)簡(jiǎn)單的二級(jí)聯(lián)動(dòng)效果的實(shí)例,具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-03-03
  • JavaScript驗(yàn)證電子郵箱的函數(shù)

    JavaScript驗(yàn)證電子郵箱的函數(shù)

    本文主要是javascript使用正則來(lái)驗(yàn)證電子郵箱的一個(gè)函數(shù)分享,很簡(jiǎn)單,但也很使用,在很多地方都可以用的到。
    2014-08-08
  • js設(shè)置控件的隱藏與顯示的兩種方法

    js設(shè)置控件的隱藏與顯示的兩種方法

    js設(shè)置控件的隱藏與顯示,設(shè)置控件style的display和visibility屬性就可以了,下面有個(gè)示例,需要的朋友可以參考下
    2014-08-08
  • 最新評(píng)論