$root knockout

时间:2022-06-05 17:08:56

http://www.cnblogs.com/rohelm/p/3209757.html

以列表方式呈现数据

   处理以数组形式储存的多条数据,要先认识foreach。在ViewModel定义一个JavaScript Array或是ko.observableArray() (observableArray在新增或剔除数组元素时,KO会立刻察觉反应到UI,普通Array则不会),然后在某个容器元素(例如: div, ul, tbody... )声明data-bind="foreach: arrayPropName",就可以指定KO将容器内的子元素模板(Template)就会对数组对象的数据自动循环遍历,例如:

$root  knockout
<tbody data-bind="foreach: users">
<tr>
<td><span data-bind="text: id"></span></td>
<td><span data-bind="text: name"></span></td>
<td><span data-bind="text: score" style='text-align: right'></span></td>
<td><a href='#' data-bind="click: $root.removeUser">移除</a></td>
</tr>
</tbody>
$root  knockout

在上面的例子中,我们假设ViewModel有一个数组属性—users,其中每笔数据对象都有id, name, score三个属性,在tbody上宣告data-bind="foreach: users",意味者<tbody>到</tbody>间的内容,会依users数组的元素多寡重复出现n次。而其中元素(如<span>, <a>)系结对象便是users中的每一条用户数据,因此只要写上data-bind="text: id"就可以对应到用户的id属性。最后一个<td>中出现了<a data-bind="click: $root.removeUser">,你一定可以猜想它可用来移除该用户数据,$root是一个特殊变量,会指向ViewModel个体。在这里必须加上的原因是我们在ViewModel定义了remoteUser方法,但在<tbody>中,默认绑定的对象是users对象,若只写data-bind="click: removeUser",KO会误认成users对象上的removeUser方法。加上$root,KO会改由ViewModel的最上层寻找removeUser方法。

removeUser的定义如下:

self.removeUser = function(user) {
self.users.remove(user);
}

当它在foreach范围被点击触发时,会接收到一个参数,指向被点击的那条数据对象。所以,只需self.users.remove(user)就可以将该条数据从observableArray移除,网页也会马上做出回应,该条数据的<tr>会立刻从<tbody>中消失。

如果要新增用户数据,在observableArray中加入一条具有id, name, score三个属性的对象即可,为了规范组件包含所有必要属性,我们将user定义成function模拟ViewModel形式的对象:

 function UserViewModel(id, name, score) {
var self = this;
self.id = id;
self.name = name;
self.score = score;
}

如此新增数据时即可写成viewModel.users.push(new UserViewModel("0001", "halower", 125)),为了展现KO可以实时监控obervableArray的风吹草动,我们写一个ko.computed计算所有用户的score总和:

$root  knockout
self.totalScore = ko.computed(function () {
var total = 0;
$.each(self.users(), function (i, u) {
total += u.score;
});
return total;
});
$root  knockout
并在表格最上方加上
共 <span data-bind="text: users().length"></span> 条,
合计 <span data-bind="text: totalScore"></span> 分
如此,一旦users数据有所增删,不但列表表格会马上反应,笔数及积分统计也会立刻呈现最新结果。

完整代码如下:

$root  knockout
<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index2</title>
<script src="~/Scripts/jquery-2.0.3.js"></script>
<script src="~/Scripts/knockout-2.3.0.js"></script>
<script type="text/javascript">
//定义user数据对象
function UserViewModel(id,name,score) {
var self = this;
self.id = id;
self.name = name;
self.score = score;
}
//定义ViewModel
function ViewModel() {
var self = this;
self.users = ko.observableArray();//添加动态监视数组对象
self.removeUser = function (user) {
self.users.remove(user);
}
self.totalscore = ko.computed(function () {
var total = 0;
$.each(self.users(), function (i, u) {
total += u.score;
})
return total;
});
};
$(function () {
var vm = new ViewModel();
//预先添加一些数据
vm.users.push(new UserViewModel("d1", "rohelm", 121));
vm.users.push(new UserViewModel("d2", "halower", 125));
$("#btnAddUser").click(function () {
vm.users.push(new UserViewModel(
$("#u_id").val(),
$("#u_name").val(),
parseInt($("#u_score").val())));
});
ko.applyBindings(vm);
});
</script>
</head>
<body>
<section style="margin:250px">
<section>
ID<input type="text" id="u_id" style="width:30px">
Name<input type="text" id="u_name" style="width:30px">
Score<input type="text" id="u_score" style="width:30px"><br/>
<input value="Add" id="btnAddUser" type="button" style="width:200px; "/><br/>
共 <span data-bind="text: users().length"></span> 条--------------合计 <span data-bind="text: totalscore"></span> 分
</section>
<section>
<table>
<thead>
<tr><th>ID</th><th>Name</th><th>Score </th><th>Option</th></tr>
</thead>
<tbody data-bind="foreach: users">
<tr>
<td><span data-bind="text: id"></span></td>
<td><span data-bind="text: name"></span></td>
<td><span data-bind="text: score"></span></td>
<td><a href='#' data-bind="click: $root.removeUser">Remove</a></td>
</tr>
</tbody>
</table>
</section>
</section>
</body>
</html>
$root  knockout

效果演示:

$root  knockout

随机推荐

  1. 关于js的keycode13

    一个form 里面只有一个input的时候  触发keydown 之类的事件  表单会在你的动作之外再次提交一次.并且 字段使用的是input的id  而不是name  可以在form上加一个onsu ...

  2. Linux软件安装-RPM安装

    RPM是RPM Package Manager(RPM软件包管理器)的缩写,这一文件格式名称虽然打上了RedHat的标志,但是其原始设计理念是开放式的,现在包括OpenLinux.         S ...

  3. telnet连接ip

    win7 telnet命令无法开启的解决方案(不是内部命令或外部命令) 出处:西西整理 作者:西西 日期:2012-12-21 14:22:06 [大 中 小] 评论: 0 | 我要发表看法 如果你想 ...

  4. SourceGrid zt

    SourceGrid介绍和使用及实例举例 先上图,来一个简单演示: SourceGrid就是一个用于数据显示的表格控件,这个控件比c#自带的 DataGridView要强大很多,先不说他的原理,只说他 ...

  5. debian安装vld来查看Opcode&comma;PHP调优。

    一: 我的环境: Debian 7 (wheezy)  x64 PHP 5.4.4-14 (apt-get 而来) Apache/2.2.22 (同上,非源码编译) 二 :安装vld. (# 代表是r ...

  6. &lbrack;Swift-2019力扣杯春季初赛&rsqb;3&period; 最小化舍入误差以满足目标

    给定一系列价格 [p1,p2...,pn] 和一个目标 target,将每个价格 pi 舍入为 Roundi(pi) 以使得舍入数组 [Round1(p1),Round2(p2)...,Roundn( ...

  7. Selenium Java关闭浏览器

    在学习selenium的过程中发现一个问题,各种博客/教程都是教人用selenium的quit()和close()方法关闭浏览器. 但这不是我要的结果.这两个方法的前提是,用webdriver打开浏览 ...

  8. 3&period;翻译系列:EF Code-First 示例&lpar;EF 6 Code-First系列&rpar;

    原文链接:http://www.entityframeworktutorial.net/code-first/simple-code-first-example.aspx EF 6 Code-Firs ...

  9. Oracle Applications Documentation

    Oracle E-Business Suite Documentation Web Library Release 12.2+ Link Download Oracle E-Business Suit ...

  10. Assembly&period;Load&lpar;&rpar;方法,Assembly&period;LoadFrom&lpar;&rpar;方法,Assembly&period;LoadFile&lpar;&rpar;方法的区别!

    参考: http://www.cnblogs.com/benwu/archive/2009/10/24/1589096.html http://www.cnblogs.com/xuefeng1982/ ...