新浦京娱乐场官网-301net-新浦京娱乐www.301net
做最好的网站

不需要重新刷新整个控件片段或自己写JS增删节点

在上篇作品给大家介绍了BootstrapTable与KnockoutJS相结合贯彻增加和删除改查作用【一】,介绍了下knockout.js的有个别基础用法。接下来通过本文继续给大家介绍。假若您也筹算用ko去做项目,且看看吧!

Bootstrap是贰个前端框架,解放Web开垦者的好东东,表现出的UI相当高等大气上档期的顺序,理论上得以不用写一行css。只要在标签中加上适当的性质就能够。

KnockoutJS是贰个JavaScript落成的MVVM框架。非常厉害。举个例子列表数据项增减后,不供给重新刷新整个控件片段或和睦写JS增加和删除节点,只要预先定义模板和适合其语法定义的品质即可。一言以蔽之,大家只须求关心数据的存取。

一、效果预览

实质上也没啥功效,就是简单的增删改查,入眼依然在代码上边,使用ko能够大批量节省分界面DOM数据绑定的操作。下边是任何整个增加和删除改查逻辑的js代码:

图片 1

页面效果:

图片 2

图片 3

二、代码示例

好了,步入第一吧!博主计划分两块介绍,第一部分是表格开头化部分,第二某些是按键操作增删改部分。

1、表格初阶化

1.1、计划干活

首先拜谒必要援用的js和css文件

<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="~/Content/bootstrap-table/knockout.bootstraptable.js"></script>
<script src="~/scripts/Department.js"></script> 

都以某些常用的css和js文件,大家自定义的js文件注重有四个: knockout.bootstraptable.js 和 Department.js 。上篇大家介绍过使用ko能够自定义我们的data-bind。同样,这里对于table的绑定,大家也定义二个自定义的绑定,代码 knockout.bootstraptable.js 里面。

//添加ko自定义绑定
ko.bindingHandlers.myBootstrapTable = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
//这里的oParam就是绑定的viewmodel
var oViewModel = valueAccessor();
var $ele = $(element).bootstrapTable(oViewModel.params);
//给viewmodel添加bootstrapTable方法
oViewModel.bootstrapTable = function () {
return $ele.bootstrapTable.apply($ele, arguments);
}
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {}
};
//初始化
(function ($) {
//向ko里面新增一个bootstrapTableViewModel方法
ko.bootstrapTableViewModel = function (options) {
var that = this;
this.default = {
search: true, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
strictSearch: true,
showColumns: true, //是否显示所有的列
cache:false,
showRefresh: true, //是否显示刷新按钮
minimumCountColumns: 2, //最少允许的列数
clickToSelect: true, //是否启用点击选中行
showToggle: true,
};
this.params = $.extend({}, this.default, options || {});
//得到选中的记录
this.getSelections = function () {
var arrRes = that.bootstrapTable("getSelections")
return arrRes;
};
//刷新
this.refresh = function () {
that.bootstrapTable("refresh");
};
};
})(jQuery); 

代码释疑:那么些js文件根本做了两件事

1.自定义data-bind属性myBootstrapTable。对于ko.bindingHandlers.myBootstrapTable里面包车型地铁update方法,如非必须,能够不用定义。

2.经过向ko对象里面加多bootstrapTableViewModel来封装bootstrapTable。

1.2、html标签运行绑定

<table id="tb_dept" data-bind="myBootstrapTable:$root">
<thead>
<tr>
<th data-checkbox="true"></th>
<th data-field="Name">部门名称</th>
<th data-field="Level">部门级别</th>
<th data-field="Des">描述</th>
<th data-field="strCreatetime">创建时间</th>
</tr>
</thead>
</table> 

代码释疑:定义三个table标签,使用自定义绑定myBootstrapTable,上篇说过,$root能够了解为最先化的情致。为了轻巧,全体的colums就径直在<th>里面写了。

1.3、激活ko的绑定

在页面加载成功之后,运行ko的绑定:

//初始化
$(function () {
//1、初始化表格
tableInit.Init();
//2、注册增删改事件
operate.operateInit();
});
//初始化表格
var tableInit = {
Init: function () {
//绑定table的viewmodel
this.myViewModel = new ko.bootstrapTableViewModel({
url: '/Department/GetDepartment', //请求后台的URL(*)
method: 'get', //请求方式(*)
toolbar: '#toolbar', //工具按钮用哪个容器
queryParams: function (param) {
return { limit: param.limit, offset: param.offset };
},//传递参数(*)
pagination: true, //是否显示分页(*)
sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*)
pageNumber: 1, //初始化加载第一页,默认第一页
pageSize: 10, //每页的记录行数(*)
pageList: [10, 25, 50, 100], //可供选择的每页的行数(*)
});
ko.applyBindings(this.myViewModel, document.getElementById("tb_dept"));
}
}; 

代码释疑:页面加载成功之后,调用上边封装的bootstrapTableViewModel对象合并传递的参数,最终激活绑定,将this.myViewModel作为绑定的viewmodel激活。调试代码可见,当实行到 ko.applyBindings(this.myViewModel, document.getElementById("tb_dept")); 这一句的时候,自定义绑定才会卓有成效,程序才会进去到 ko.bindingHandlers.myBootstrapTable 对象的init方法去开始化bootstrapTable。这里须求表明有些:

init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
//这里的oParam就是绑定的viewmodel
var oViewModel = valueAccessor();
var $ele = $(element).bootstrapTable(oViewModel.params);
//给viewmodel添加bootstrapTable方法
oViewModel.bootstrapTable = function () {
return $ele.bootstrapTable.apply($ele, arguments);
}
}

上文中的init方法,通过第4个参数valueAccessor,大家获得的是日前绑定的viewmodel,也正是我们地点的this.myViewModel那些指标,博主认为那点福利你明白自定义绑定的逻辑。基本上施行到 var $ele = $(element).bootstrapTable(oViewModel.params); 这一句的时候,我们表格的开始化就完事了。后台对应的法子博主随意定义了一个会晤,为了完整,这里如故贴出来:

DepartmentController

2、开关操作

位置通过bootstrapTable的开头化完毕了我们的自定义data-bind的施用。上面包车型地铁开关操作大家来感受一把施用监控属性的“爽歪歪”。

2.1、view页面

首先在view页面下面定义大家的增加和删除改开关

<div id="toolbar" class="btn-group">
<button id="btn_add" type="button" class="btn btn-default">
新增
</button>
<button id="btn_edit" type="button" class="btn btn-default">
修改
</button>
<button id="btn_delete" type="button" class="btn btn-default">
删除
</button>
</div> 

为了省事,博主使用了三个潜藏的弹出框用来含有新扩充和编辑的文本框。当然,一般情况下,大概那边用的是一对视图,你的品类里面或许会有三个Edit.cshtml,但此间博主将这一个都位居二个页面上边,因为那不是文本的基本点。

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
<h4 class="modal-title" id="myModalLabel">操作</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="txt_departmentname">部门名称</label>
<input type="text" name="txt_departmentname" data-bind="value:Name" class="form-control" id="txt_departmentname" placeholder="部门名称">
</div>
<div class="form-group">
<label for="txt_departmentlevel">部门级别</label>
<input type="text" name="txt_departmentlevel" data-bind="value:Level" class="form-control" id="txt_departmentlevel" placeholder="部门级别">
</div>
<div class="form-group">
<label for="txt_des">描述</label>
<input type="text" name="txt_des" data-bind="value:Des" class="form-control" id="txt_des" placeholder="描述">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="button" id="btn_submit" class="btn btn-primary" data-dismiss="modal">保存</button>
</div>
</div>
</div>
</div> 

2.2、JS初步化按键操作

//操作
var operate = {
//初始化按钮事件
operateInit: function () {
this.operateAdd();
this.operateUpdate();
this.operateDelete();
this.DepartmentModel = {
id: ko.observable(),
Name: ko.observable(),
Level: ko.observable(),
Des: ko.observable(),
CreateTime: ko.observable()
};
},
//新增
operateAdd: function(){
$('#btn_add').on("click", function () {
$("#myModal").modal().on("shown.bs.modal", function () {
var oEmptyModel = {
id: ko.observable(),
Name: ko.observable(),
Level: ko.observable(),
Des: ko.observable(),
CreateTime: ko.observable()
};
ko.utils.extend(operate.DepartmentModel, oEmptyModel);
ko.applyBindings(operate.DepartmentModel, document.getElementById("myModal"));
operate.operateSave();
}).on('hidden.bs.modal', function () {
ko.cleanNode(document.getElementById("myModal"));
});
});
},
//编辑
operateUpdate: function () {
$('#btn_edit').on("click", function () {
$("#myModal").modal().on("shown.bs.modal", function () {
var arrselectedData = tableInit.myViewModel.getSelections();
if (!operate.operateCheck(arrselectedData)) { return; }
//将选中该行数据有数据Model通过Mapping组件转换为viewmodel
ko.utils.extend(operate.DepartmentModel, ko.mapping.fromJS(arrselectedData[0]));
ko.applyBindings(operate.DepartmentModel, document.getElementById("myModal"));
operate.operateSave();
}).on('hidden.bs.modal', function () {
//关闭弹出框的时候清除绑定(这个清空包括清空绑定和清空注册事件)
ko.cleanNode(document.getElementById("myModal"));
});
});
},
//删除
operateDelete: function () {
$('#btn_delete').on("click", function () {
var arrselectedData = tableInit.myViewModel.getSelections();
$.ajax({
url: "/Department/Delete",
type: "post",
contentType: 'application/json',
data: JSON.stringify(arrselectedData),
success: function (data, status) {
alert(status);
//tableInit.myViewModel.refresh();
}
});
});
},
//保存数据
operateSave: function () {
$('#btn_submit').on("click", function () {
//取到当前的viewmodel
var oViewModel = operate.DepartmentModel;
//将Viewmodel转换为数据model
var oDataModel = ko.toJS(oViewModel);var funcName = oDataModel.id?"Update":"Add";
$.ajax({
url: "/Department/" funcName,
type: "post",
data: oDataModel,
success: function (data, status) {
alert(status);
tableInit.myViewModel.refresh();
}
});
});
},
//数据校验
operateCheck:function(arr){
if (arr.length <= 0) {
alert("请至少选择一行数据");
return false;
}
if (arr.length > 1) {
alert("只能编辑一行数据");
return false;
}
return true;
}
} 

代码释疑:说说这里的实行逻辑,首先在$(function(){})方法里面调用 operate.operateInit(); 。在operateInit()方法里面注册页面上边开关的点击事件,同期也定义 this.DepartmentModel 作为我们新扩张编写制定的viewmodel,这一个viewmodel里面定义了和页面成分对应的监督属性。还记得上边掩盖的弹出框里面包车型大巴一部分data-bind吗,没错,里面对应的value值正是和这里的监察属性对应,那样设置绑定之后,js里面全数的诱致 this.DepartmentModel 里面监察和控制的转换,都会触发分界面上面这么些绑定标签的value值变化,反之,分界面上面的具有标签的Value值的更换,也势必会引起它的督察属性值的浮动,此之所谓双向绑定。上边具体看看双向绑定的施行。

2.3、新扩展操作

$('#btn_add').on("click", function () {
$("#myModal").modal().on("shown.bs.modal", function () {
var oEmptyModel = {
id: ko.observable(),
Name: ko.observable(),
Level: ko.observable(),
Des: ko.observable(),
CreateTime: ko.observable()
};
ko.utils.extend(operate.DepartmentModel, oEmptyModel);
ko.applyBindings(operate.DepartmentModel, document.getElementById("myModal"));
operate.operateSave();
}).on('hidden.bs.modal', function () {
ko.cleanNode(document.getElementById("myModal"));
});
}); 

当咱们分界面触发新扩充操作的时候,首先会弹出地点说的隐形模态框。在模态框展现的时候,首先定义一个空的viewmodel,然后调用 ko.utils.extend(operate.DepartmentModel, oEmptyModel); 这一句,将全局的operate.DepartmentModel被空的viewmodel覆盖。ko.utils.extend()这些艺术的机能和jquery里面包车型大巴$.extend()功能类似,都以依附前面前碰着象合并前边对象,合併之后,使用新的viewmodel激活绑定。激活绑定之后,注册保存开关的click事件。那样新添的时候,弹出模态框,由于viewmodel里面的督察属性都以空的,对应分界面成分的value也会被清空,所以新添大家看出是这么:

图片 4

当弹出框关闭后,大家经过关闭的平地风波,试行ko.cleanNode(document.getElementById("myModal")); 这一句,那一个很首要,因为对此同贰个dom,ko只好绑定三次,如果须要再行绑定,供给先清空绑定,而且cleanNode()这么些法子,它不只会清空绑定,依然会dom里面注册的平地风波也会清空,使用的时候需求专注下!

2.4、编辑操作

$('#btn_edit').on("click", function () {
$("#myModal").modal().on("shown.bs.modal", function () {
var arrselectedData = tableInit.myViewModel.getSelections();
if (!operate.operateCheck(arrselectedData)) { return; }
//将选中该行数据有数据Model通过Mapping组件转换为viewmodel
ko.utils.extend(operate.DepartmentModel, ko.mapping.fromJS(arrselectedData[0]));
ko.applyBindings(operate.DepartmentModel, document.getElementById("myModal"));
operate.operateSave();
}).on('hidden.bs.modal', function () {
//关闭弹出框的时候清除绑定(这个清空包括清空绑定和清空注册事件)
ko.cleanNode(document.getElementById("myModal"));
});
}); 

当大家接触编辑操作的时候,分界面依然弹出框。在弹出框的弹出事件之中,大家取到当前当选的行,然后校验是还是不是选中了一条龙。最棒通过 ko.mapping.fromJS(arrselectedData[0]) 这一句,将一般的Json对象转换为含有监察和控制属性的viewmodel,上篇说过,这几个措施须要knockout.mapping-latest.js 这么些js文件的匡助。转换之后,照旧经过ko.utils.extend()方法立异viewmodel,然后激活绑定。由于viewmodel被日前选中央银行的多寡更新了,所以获得结果:

图片 5

2.5、保存操作

在新添和编辑弹出框之后,修改相关新闻后点击保存,就能够触发保存事件。

$('#btn_submit').on("click", function () {
//取到当前的viewmodel
var oViewModel = operate.DepartmentModel;
//将Viewmodel转换为数据model
var oDataModel = ko.toJS(oViewModel);
var funcName = oDataModel.id?"Update":"Add";
$.ajax({
url: "/Department/" funcName,
type: "post",
data: oDataModel,
success: function (data, status) {
alert(status);
tableInit.myViewModel.refresh();
}
});
}); 

当接触保存事件的时候,大家先是取到页面绑定的viewmodel,即operate.DepartmentModel,然后使用ko.toJS()方法将含有监控属性的viewmodel转变为纯数据的Json对象,那一个办法是ko内置的,无需别的js支持。获得json对象之后,发送ajax哀告,去新增添只怕编辑数据。那样就很好地反映了双向绑定,分界面下面装有文本框的value发生了转移以往,也会触发operate.DepartmentModel的生成。

2.6、删除操作

删去操作没什么好说的,和ko关系十分的小。

三、总结

如上通过二个粗略的增加和删除改查操作,介绍了下ko和bootstrapTable的联手利用。ko能够让您从DOM中解放出来,把关切点放在viewmodel上面。纵观整个js代码,差不离看不到jquery的val()、text()等对分界面dom做取值和赋值的操作,是否看着彻底清爽,而且高大上了呢~~当然,那也许只是ko的部分比较基础的用法,毕竟博主学习ko才3天,越来越多高级用法还大概有待探寻,等过段日子用熟了,再将它的局地尖端用法分享给大家。如若你以为本文能够援救你知道ko的准绳以及它的一部分用法,无妨推荐下,小编在此感谢不尽!

如上所述是作者给我们介绍的BootstrapTable与KnockoutJS相结合贯彻增删改查功用【二】的全部内容,希望对我们持有帮衬!

你恐怕感兴趣的小说:

  • BootstrapTable KnockoutJS自定义T4模板快速生成增加和删除改查页面
  • Knockoutjs 学习类别(一)ko初体验
  • KnockoutJs火速入门教程
  • knockoutjs模板达成树形结构列表

本文由新浦京娱乐场官网-301net-新浦京娱乐www.301net发布于www.301net,转载请注明出处:不需要重新刷新整个控件片段或自己写JS增删节点

您可能还会对下面的文章感兴趣: