Knock Out.js 循环遍历和click 绑定
在knonck out中,绑定是实现KO的基本条件,常用的绑定我们使用“data-bind” 这个html属性就可以实现简单的绑定。但是最近在工作中遇到一些特殊的情况 例如 Foreach循环不依赖绑定属性和click绑定时参数传递的问题 ,就去网上找资料解决,结果又学到了一些新的使用方法。所以简单记录一下:
Foreach 循环
<tbody data-bind="foreach: people">
<tr>
<td data-bind="text: firstName"></td>
<td data-bind="text: lastName"></td>
</tr>
</tbody>
<script>
var viewModel={
people:ko.observableArray([
{firstName:"張",lastName:"三峰"}
]),
}
</script>
以上的代码就是一个简单的循环,循环people 数组。 firstName 和 lastName 就是定义的属性。 同时您也可以使用$data.firstName 来实现绑定,$data就是当前的上下文对象,也就是“张三峰”这个对象,如下代码
<tbody data-bind="foreach: people">
<tr>
<td data-bind="text: $data.firstName"></td>
<td data-bind="text: $data.lastName"></td>
</tr>
</tbody>
在Knockout 中还会用到$parent,$root ,他们三个的区别如下:
屬性 | 作用 |
$data | 表示当前的上下文对象,代表当前使用对象 |
$root | 表示父级元素(最外层的父级) |
$parent | 返回父级元素(当前对象的父级) |
了解了上述的概念后看以下代码:
<tbody data-bind="foreach: Items ">
<tr>
<td data-bind="text: $data.firstName"></td>
<td data-bind="text: $parent.match_mdl"></td>
<td data-bind="text: $root.chkAll"></td>
</tr>
</tbody>
<script>
var viewModel = {
match_mdl : ko.observable(""),//監控變量
chkAll: ko.observable(false),//監控變量
Items : ko.observableArray([]),//監控數組
}
</script>
在上面的循环代码中,第一列#data表示绑定监控数组当前对对象中的firstName属性。 第二列$parent表示的是绑定当前对象的父级对象,那么当前对象是监控数组“Items”,它的父级就是。 所以绑定的是viewModel下的match_mdl。 第三列$root表示最外层的对象,在上面的代码中最外层就是viewModle,绑定的就是viewModel下的chkAll。
使用 “as”来为便利的数组设置别名:
通过上面的代码我们可以知道使用$data 就可以代替当前的数组元素,同理我们也可以设置别名来代替当前的数组,如下:
<tbody data-bind="foreach: {data: items,as:'name'}Items ">
<tr>
<td data-bind="text: name.firstName"></td>
<td data-bind="text: name.match_mdl"></td>
<td data-bind="text: name.chkAll"></td>
</tr>
</tbody>
<script>
var viewModel = {
match_mdl : ko.observable(""),//監控變量
chkAll: ko.observable(false),//監控變量
Items : ko.observableArray([]),//監控數組
}
</script>
另外这里使用了另外一种绑定Foreach 的语法, 不同的是绑定多了属性:data 和as ,data 表示的是要循环的数组对象,as 是我们设置的别名 ,注意:是使用 时要加单引号。
在没有绑定数字属性的情况下使用forrach:
通过上面的案例我们可以发现所有的绑定都是写在Html元素上的。 有些特殊的情况需特殊的内容,例如在下面的案例中需要实现一个动态列,这些列的内容来自我们定义的数组,这个是时候没有让我们绑定属性的元素,我们就可以像下面这样写。
<tbody data-bind="foreach: Items ">
<tr>
<td data-bind="text: $data.firstName"></td>
<!-- ko foreach: {data:$parent.lineItems,as:'line'} --> 注釋語法開始
<td data-bind="text:line.lineName"></td>
<!-- /ko --> 注釋語法結束
<td data-bind="text: $root.chkAll"></td>
</tr>
</tbody>
我们使用<!--ko--><!--/ko-->来表示循环的开始和结束,这是一个虚拟的标签,Knockoutjs能够对其中的foreach进行绑定就好像你将foreach绑定到了一个真实的标签上一样。这种语法的与HTML注释很相似,所以也叫注释语法,在使用时注意书写格式。此外比较常用的注释语法还有 if ,写法与其类似
Click 绑定:
click 绑定是在DOM 元素上添加click 事件,它可以调用任何javaScript函数,不一定得是viewModel 中的方法
这个方法和普通的绑定很相似 。如下
<div data-bind="click:myClick" class="d1">
<button data-bind="click:myClick2,clickBubble:false " class="d2">
Click me(view Model)
</button>
<button data-bind="click:clickMe,clickBubble:false" class="d2">
Click me(no viewModel)
</button>
</div>
<script type="text/javascript">
var viewModel = {
myFunction: function (data, event, name) {
alert("name")
},
myClick2: function () {
alert("name2")
},
myClick: function () {
alert("Div")
}
};
ko.applyBindings(viewModel);
function clickMe() {
alert("我不是vireModel 里的方法")
}
</script>
click 事件默认是向上冒泡的,“clickBubble=false” 时可以阻止事件冒泡,以上就是简单的click 绑定。
但是通常我们的事件往往都是由参数的传递的,在knock 中点击绑定点击事件时候会默认传递两个参数,当前的对象和点击的事件类型, 如下我们删除数组中的一条记录。
<button data-bind="click:$parent.removeButton1">
删除1
</button>
<script>
var vm = {
name: ko.observable("name"),
weeks: ko.observableArray([
{ week: "星期一", work: "乱八七糟",act_flg:"false",seq:1 },
{ week: "星期二", work: "稍有头绪", act_flg: "false",seq: 2 },
{ week: "星期三", work: "认真工作", act_flg: "false", seq: 3},
{ week: "", work: "自我复习", act_flg: "false", seq: 4 },
{ week: "星期五", work: "快乐一天", act_flg: "false", seq: 5},
]),
logtext: ko.observable()
}
//删除按钮
vm.removeButton1 = function (obj1, obj2,obj3) {
console.log(obj1);
console.log(obj2);
console.log(obj3);
}
ko.applyBindings(vm)
</script>
输出结果:
如果要传入参数,需要注意的是不能直接使用函数传入参数,会导致在页面刷新的时候就执行了被调用的函数,这显然不符合我们的使用条件。如下:
<button data-bind="click:$parent.removeButton1.bind($data,12)">
删除2
</button>
如果这样写就会导致页面加载的时候函数removeButton1 就被调用。
实现参数的传递有两种方法:
方法一:使用函数包裹
<button data-bind="event: { click: function(data, event) {$parent.removeButton1('param1', 'param2', data, event) } }">
删除2
</button>
<script>
//数组省略,这里只写了调用的方法
var viewModel={
}
viewModel.removeButton1 = function (obj1, obj2,obj3,obj4) {
console.log(obj1);
//console.log('pramr1=' + data + 'pramr2=' + obj2 + 'pramr' + a);
console.log(obj2);
console.log(obj3);
console.log(obj4);
}
</script>
输出结果:
方法二:使用bind 函数:
<button data-bind="event: { click: $parent.removeButton1.bind($data, 'param1', 'param2') }">
删除3
</button>
<script>
//只贴了被调用的函数
vm.removeButton1 = function (obj1, obj2,obj3,obj4) {
console.log(obj1);
//console.log('pramr1=' + data + 'pramr2=' + obj2 + 'pramr' + a);
console.log(obj2);
console.log(obj3);
console.log(obj4);
}
</script>
输出结果:
这里“$data”是形式化写法,就是使用“bind”绑定的函数传入的第一个参数只能是'$data',后面接我们要传入的参数。但实际传入的第一个参数是 “param1” 而不是$data。
注意:使用bind 传递参数的写法,data 和 event 是会被缺省传递的,data和 event 排在新加入方法参数的后面 ,例如方法二只有参数param1 和param2 但是输出的结果在param1和 param2 后面还有data 和 event 。
以上就是关于foreach 和click 事件参数传递的内容,感谢阅读。