在大多数情况下,数据绑定属性提供了一种干净和简洁的方式来绑定到视图模型。 然而,事件处理是一个常常会导致详细数据绑定属性的领域,因为匿名函数通常是传递参数的推荐技术。 例如:

<a href="#" data-bind="click: function() { viewModel.items.remove($data); }">
remove
</a>

作为替代,Knockout提供了两个帮助函数,它们允许您标识与DOM元素关联的数据:

  • ko.dataFor(element) - 返回可用于与元素绑定的数据

  • ko.contextFor(element) - 返回DOM元素可用的整个绑定上下文

这些帮助函数可以在事件处理程序中使用,这些事件处理程序使用类似于jQuery的绑定或单击的方式地附加。 上面的函数可以连接到每个链接一个删除类,如:

$(".remove").click(function () {
viewModel.items.remove(ko.dataFor(this));
});

更好的是,这种技术可以用于支持事件委托。 jQuery live / delegate / on函数是一个简单的方法来实现这一点:

$(".container").on("click", ".remove", function() {
viewModel.items.remove(ko.dataFor(this));
});

现在,单个事件处理程序在更高级别附加,并处理与remove类的任何链接的点击。 此方法还具有自动处理动态添加到文档的附加链接(可能是由于项目添加到observableArray的结果)的额外好处。

示例:嵌套子节点

此示例显示父级和子级的多个级别上的“add”和“remove”链接,每个类型的链接具有单个处理程序。

UI源码:

<ul id="people" data-bind='template: { name: "personTmpl", foreach: people }'>
</ul> <script id="personTmpl" type="text/html">
<li>
<a class="remove" href="#"> x </a>
<span data-bind='text: name'></span>
<a class="add" href="#"> add child </a>
<ul data-bind='template: { name: "personTmpl", foreach: children }'></ul>
</li>
</script>

视图模型源码:

var Person = function(name, children) {
this.name = ko.observable(name);
this.children = ko.observableArray(children || []);
}; var PeopleModel = function() {
this.people = ko.observableArray([
new Person("Bob", [
new Person("Jan"),
new Person("Don", [
new Person("Ted"),
new Person("Ben", [
new Person("Joe", [
new Person("Ali"),
new Person("Ken")
])
]),
new Person("Doug")
])
]),
new Person("Ann", [
new Person("Eve"),
new Person("Hal")
])
]); this.addChild = function(name, parentArray) {
parentArray.push(new Person(name));
};
}; ko.applyBindings(new PeopleModel()); //attach event handlers
$("#people").on("click", ".remove", function() {
//retrieve the context
var context = ko.contextFor(this),
parentArray = context.$parent.people || context.$parent.children; //remove the data (context.$data) from the appropriate array on its parent (context.$parent)
parentArray.remove(context.$data); return false;
}); $("#people").on("click", ".add", function() {
//retrieve the context
var context = ko.contextFor(this),
childName = context.$data.name() + " child",
parentArray = context.$data.people || context.$data.children; //add a child to the appropriate parent, calling a method off of the main view model (context.$root)
context.$root.addChild(childName, parentArray); return false;
});

无论嵌套链接如何嵌套,处理程序总是能够识别和操作适当的数据。 使用这种技术,我们可以避免将处理程序附加到每个链接的开销,并可以保持标记清洁和简洁。

KnockoutJS 3.X API 第七章 其他技术(5) 使用其他事件处理程序的更多相关文章

  1. KnockoutJS 3.X API 第七章 其他技术(4) 速率限制

    注意:这个速率限制API是在Knockout 3.1.0中添加的. 通常,更改的observable立即通知其订户,以便依赖于observable的任何计算的observable或绑定都会同步更新. ...

  2. KnockoutJS 3.X API 第七章 其他技术(8) 异步错误处理

    注意:本文档适用于Knockout 3.4.0及更高版本. ko.onError Knockout包装内部异步调用,并在抛出原始错误之前查找可选的ko.onError回调以执行(如果遇到异常). 这使 ...

  3. KnockoutJS 3.X API 第七章 其他技术(7) 微任务

    注意:本文档适用于Knockout 3.4.0及更高版本. Knockout的微任务队列 Knockout的微任务队列支持调度任务尽可能快地运行,同时仍然是异步的,努力安排它们在发生I / O,回流或 ...

  4. KnockoutJS 3.X API 第七章 其他技术(6) 使用“fn”添加自定义函数

    有时,您可能会通过向Knockout的核心值类型添加新功能来寻找机会来简化您的代码. 您可以在以下任何类型中定义自定义函数: 因为继承,如果你附加一个函数到ko.subscribable,它将可用于所 ...

  5. KnockoutJS 3.X API 第七章 其他技术(3) 延迟更新

    .example { display: inline-block; padding: 1em; margin-right: 2em; background: #F6F6EF; } 注意:本文档适用于K ...

  6. KnockoutJS 3.X API 第七章 其他技术(2) 使用扩展器来增加可观察量(监控属性)

    Knockout observables提供了支持读取/写入值并在值改变时通知订阅者所需的基本功能. 但在某些情况下,您可能希望向可观察者添加其他功能. 这可能包括通过在可观察者前面放置一个可写的计算 ...

  7. KnockoutJS 3.X API 第七章 其他技术(1) 加载和保存JSON数据

    Knockout允许您实现复杂的客户端交互性,但几乎所有Web应用程序还需要与服务器交换数据,或至少将本地存储的数据序列化. 最方便的交换或存储数据的方式是JSON格式 - 大多数Ajax应用程序今天 ...

  8. KnockoutJS 3.X API 第六章 组件(3) 组件绑定

    组件绑定将指定的组件注入到元素中,并且可选地将参数传递给它. 本节目录 一个例子 API 组件生命周期 备注1:仅限模板组件 备注2:使用没有容器元素的组件 备注3:将标记传递给组件 处置和内存管理 ...

  9. KnockoutJS 3.X API 第六章 组件(5) 高级应用组件加载器

    无论何时使用组件绑定或自定义元素注入组件,Knockout都将使用一个或多个组件装载器获取该组件的模板和视图模型. 组件加载器的任务是异步提供任何给定组件名称的模板/视图模型对. 本节目录 默认组件加 ...

随机推荐

  1. Windows安装程序 报错 “已安装了较新版本” 导致无法安装程序的解决方法

    打开注册表 HKEY_CURRENT_USER\Software\Microsoft\Installer\Products ,“查找”程序名称 如果有程序名和安装程序相同的 ,删除整个 项 ! 然后就 ...

  2. Linux查看系统运行情况

    http://elinux.org/Runtime_Memory_Measurement

  3. files list file for package 'xxx' is missing final newline

    #!/usr/bin/python # 8th November, 2009 # update manager failed, giving me the error: # 'files list f ...

  4. Lua 排行榜更新

    排行榜: key:玩家名字,val:玩家的数值 local key1 = {"a1", "a2", "b1", "b2" ...

  5. [VijosP1764]Dual Matrices 题解

    题目大意: 一个N行M列的二维矩阵,矩阵的每个位置上是一个绝对值不超过1000的整数.你需要找到两个不相交的A*B的连续子矩形,使得这两个矩形包含的元素之和尽量大. 思路: 预处理,n2时间算出每个点 ...

  6. android copy项目后修改项目名

    有个eclipse下的Android项目,现在因为有个需求想在复制出来一个项目,把这个项目变成两个独立项目.在同一个工作空间下不能同时存在项目名称一样的项目,所以需要修改项目名.具体操作如下: 1.修 ...

  7. 关于 IE6、 IE7兼容性总结(转)

    其实浏览器的不兼容,我们往往是各个浏览器对于一些标准的定义不一致导致的,因此,我们可以进行一些初始化,很多问题都很轻松解决. 下面是14条特殊情况仅供参考: 1. 文字本身的大小不兼容.同样是font ...

  8. Win32 OpenProcess打开进程失败,返回5无权限操作

    Win32 OpenProcess打开进程失败,返回5无权限操作,相信你会碰到这样的事,在IDE中可以,单独却不可以了,其实这时就需要提权了,否则是无法打开的,OpenProcess提权至Debug即 ...

  9. 李洪强iOS经典面试题155 - const,static,extern详解(面试必备)

    李洪强iOS经典面试题155 - const,static,extern详解(面试必备) 一.const与宏的区别(面试题): const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽 ...

  10. Apache error: 403 Forbidden You don't have permission to access

    CentOS 6 solution: chcon -t httpd_sys_content_t -R /directory refer to: https://www.centos.org/forum ...