knockoutjs总结
之前写的两篇博客
knockoutJs在项目中的使用
knockout.js做table列表
特殊变量
$root
$root指的是ko所绑定的DOM,可以解决类似于作用域的问题,一般来说with、foreach等,在对应的dom标签区间中的属性是对应于with绑定的对象以及foreach循环中每一个对象中的变量,如果想在该标签区间内使用ViewModel中的其它属性,则会报错说找不到或者未定义之类的,那么就需要使用$root来指定作用域为ViewModel.
如下代码
<div class="input_list clearfix" data-bind="with:cpafInfoCondition">
<div class="input_box clearfix">
<div class="tabs-input clearfix fl">
<p class="fl">行政区划</p>
<ul class="select fl">
<li class="selected">-请选择-</li>
<li class="option">
<ul data-bind="html:$root.divisionUl"></ul>
</li>
</ul>
</div>
.....
self.cpafInfoCondition = ko.observable({currentPage:0,
pageSize : 20,
divisionProvince : '',
cpafCno : '',
cpafName : '',
cpafStatus : '',
cpaNumBegin : '',
cpaNumEnd : '',
orgForm : ''
});
...
//区划
self.divisionUl = (function () {
$parent
$parent 是指当前DOM元素直接的外部父类(只有一层);
with绑定
参考:knockoutjs六 with 绑定
在我看来,with是一个作用域或者上下文的限制。假设对象obj={key:val},那么在with:obj下可以直接使用key,而不需要使用obj.key
with还有个作用,当with的条件是null或者是undefined,那么下面的子元素就不会加载,如果不空就加载,这样就避免了一些错误,不会当obj是null或者是undefined的时候还调用obj.key发生报错。
虚拟元素
参考:Creating custom bindings that support virtual elements
如下
<!-- ko if:cpafNameNoData -->
<tr class="no-data">
<td colspan="4">暂无符合条件的数据</td>
</tr>
<!-- /ko -->
<!-- ko foreach : cpafNameList -->
<tr class="midlist-top">
<td class="zczsbh" data-bind="text:divisionProvince"></td>
<td class="zsxm" data-bind="text:cpafNo"></td>
<td class="zszt" data-bind="text:cpafName"></td>
<td class="swsmc" data-bind="text:cpafAbbr"></td>
</tr>
<!-- /ko -->
使用<!-- ko --><!-- /ko -->
做一个虚拟节点,注意写法,在–和尖括号之间是没有空格的,个人觉得有点像vue中使用Template元素渲染的意思
事件绑定及参数传递
以click为例
- 简单绑定
data-bind="click:funcName"
- 如果有多个事件需要一起绑定
data-bind="event:{click:clickFuncName,change:changeFuncName}"
- 如果需要传递参数
默认的,knockout会传递两个参数出来。
第一个参数是自己定义的ViewModel,第二个则是触发的event
- 第一种方式
//这里的$data不可以省略
//这种方式,默认参数在最后.
data-bind="click:clickFuncName($data,'param1','param2')"
- 第二种方式
<button data-bind="click: function(data, event) { myFunction('param1', 'param2', data, event) }">
Click me
</button>
问题总结
在layer中使用knock的奇怪问题
需求:当没有数据的时候显示”没有查询到符合条件的数据”,否则显示数据
问题描述:当数据从无到有或者从有到无时,tbody再也无法显示任何内容了
问题代码如下
//layer弹出表格
layer.open({
title: '处罚信息',
type: 1,
content: $(cpafPunish),
area: ['1080px', '460px'],
success: function () {
cpafPunishViewModel = new CpafPunishViewModel();
ko.cleanNode(cpafPunish);
ko.applyBindings(cpafPunishViewModel, cpafPunish);
cpafPunishViewModel.init(data.CPAF_NO);
},
end: function () {
$(cpafPunish).hide();
}
});
......
//表格的viewmodel
function CpafPunishViewModel() {
var self = this;
self.cpafPunishNoData = ko.observable(true);
self.cpafPunishList = ko.observableArray([]);
//查询列表
self.init = function (cpafNo) {
self.cpafPunishList([]);
$.postAjax(contentPath + "/searchBfLogin/searchCpafPunish", {cpafNo: cpafNo}, function (list) {
self.cpafPunishNoData(list.length < 1);
self.cpafPunishList(list);
}, true);
}
}
下表是表格
<div id="cpafPunish" style="display: none;height:50px;margin:0 auto;" class="layer_notice">
<div class="table-wrap">
<table class="conList">
<thead>
<th width="80">行政区划</th>
<th width="150">事务所名称</th>
<th width="120">执业证书编号</th>
<th width="120">处罚类型</th>
<th width="120">做出处罚时间</th>
</thead>
<tbody class="midlist-body">
<!-- ko if: cpafPunishNoData -->
<tr class="no-data">
<td colspan="5">暂无符合条件的数据</td>
</tr>
<!-- /ko -->
<!-- ko foreach: cpafPunishList -->
<tr class="midlist-top">
<td data-bind="text:DIVISION_NAME"></td>
<td data-bind="text:CPAF_NAME"></td>
<td data-bind="text:CPAF_CNO"></td>
<td data-bind="text:PUNISH_TYPE"></td>
<td data-bind="text:FILE_DATE"></td>
</tr>
<!-- /ko -->
</tbody>
</table>
</div>
</div>
解决问题的代码如下,即只new和绑定都只一次
self.viewPunish = function (data) {
var cpafPunish = document.getElementById('cpafPunish');
layer.open({
title: '处罚信息',
type: 1,
content: $(cpafPunish),
area: ['1080px', '460px'],
success: function () {
if (cpafPunishViewModel === undefined) {
cpafPunishViewModel = new CpafPunishViewModel();
ko.cleanNode(cpafPunish);
ko.applyBindings(cpafPunishViewModel, cpafPunish);
}
cpafPunishViewModel.init(data.CPAF_NO);
},
end: function () {
$(cpafPunish).hide();
}
});
};
暂时还找不到合理的解释。
Knockout checkbox click 冲突
给checkbox绑定click,发现checkbox无法选中。网上查阅资料发现knockout在处理checkbox的checked和click时,需要一点小技巧
使用knockout同时绑定checked和click时,checkbox点击不勾选,在绑定的click事件中一定要返回true;
self.checkAll = function () {
var target = event.srcElement || event.target;
$('.sfq-all-check').prop('checked', $(target).prop('checked'));
return true;
};