KnockoutJS 3.X API 第七章 其他技术(2) 使用扩展器来增加可观察量(监控属性)
Knockout observables提供了支持读取/写入值并在值改变时通知订阅者所需的基本功能。 但在某些情况下,您可能希望向可观察者添加其他功能。 这可能包括通过在可观察者前面放置一个可写的计算可观察符来向可观察或截取写入添加额外的属性。 敲除扩展器提供了一种简单和灵活的方式来对可观察者进行这种类型的扩充。
如何创建扩展器
创建扩展器涉及向ko.extenders对象添加一个函数。 函数接受observable本身作为第一个参数和第二个参数中的任何选项。 然后它可以返回observable或返回一些新的像一个计算的observable,它以某种方式使用原来的observable。
这个简单的logChange扩展器订阅了observable,并使用控制台写入任何更改以及可配置的消息。
ko.extenders.logChange = function(target, option) {
target.subscribe(function(newValue) {
console.log(option + ": " + newValue);
});
return target;
};
您将通过调用observable的extend函数并传递包含日志Change属性的对象来使用此扩展器。
this.firstName = ko.observable("Bob").extend({logChange: "first name"});
如果firstName observable值更改为Ted,那么控制台将显示名字:Ted。
示例1:强制输入为数字
此示例创建一个扩展器,该扩展器强制对可观察对象的写入被四舍五入到可配置的精度级别。 在这种情况下,扩展器将返回一个新的可写的计算可观察,它将位于真正的可观察的拦截写入之前。
(round to whole number)
(round to two decimals)
UI源码:
<p><input data-bind="value: myNumberOne" /> (round to whole number)</p>
<p><input data-bind="value: myNumberTwo" /> (round to two decimals)</p>
视图模型源码:
ko.extenders.numeric = function(target, precision) {
//create a writable computed observable to intercept writes to our observable
var result = ko.pureComputed({
read: target, //always return the original observables value
write: function(newValue) {
var current = target(),
roundingMultiplier = Math.pow(10, precision),
newValueAsNum = isNaN(newValue) ? 0 : +newValue,
valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
//only write if it changed
if (valueToWrite !== current) {
target(valueToWrite);
} else {
//if the rounded value is the same, but a different value was written, force a notification for the current field
if (newValue !== current) {
target.notifySubscribers(valueToWrite);
}
}
}
}).extend({ notify: 'always' });
//initialize with current value to make sure it is rounded appropriately
result(target());
//return the new computed observable
return result;
};
function AppViewModel(one, two) {
this.myNumberOne = ko.observable(one).extend({ numeric: 0 });
this.myNumberTwo = ko.observable(two).extend({ numeric: 2 });
}
ko.applyBindings(new AppViewModel(221.2234, 123.4525));
注意,为了自动从UI中删除被拒绝的值,有必要在计算的observable上使用.extend({notify:'always'})。 没有这个,用户可能输入一个无效的newValue,当四舍五入得到一个不变的valueToWrite。 然后,由于模型值不会改变,因此在UI中没有更新文本框的通知。 使用{notify:'always'}会导致文本框刷新(删除被拒绝的值),即使计算的属性没有更改值。
示例2:向可观察者添加验证
此示例创建一个扩展器,允许将observable标记为必需。 这个扩展器不是返回一个新的对象,而是简单地向现有的observable添加额外的子可观察量。 因为observables是函数,它们实际上可以有自己的属性。 但是,当视图模型转换为JSON时,子可观察项将被删除,我们将只剩下我们的实际observable的值。 这是一个很好的方法来添加只与UI相关的附加功能,而不需要发送回服务器。
UI源码:
<p data-bind="css: { error: firstName.hasError }">
<input data-bind='value: firstName, valueUpdate: "afterkeydown"' />
<span data-bind='visible: firstName.hasError, text: firstName.validationMessage'> </span>
</p>
<p data-bind="css: { error: lastName.hasError }">
<input data-bind='value: lastName, valueUpdate: "afterkeydown"' />
<span data-bind='visible: lastName.hasError, text: lastName.validationMessage'> </span>
</p>
视图模型晕吗:
ko.extenders.required = function(target, overrideMessage) {
//add some sub-observables to our observable
target.hasError = ko.observable();
target.validationMessage = ko.observable();
//define a function to do validation
function validate(newValue) {
target.hasError(newValue ? false : true);
target.validationMessage(newValue ? "" : overrideMessage || "This field is required");
}
//initial validation
validate(target());
//validate whenever the value changes
target.subscribe(validate);
//return the original observable
return target;
};
function AppViewModel(first, last) {
this.firstName = ko.observable(first).extend({ required: "Please enter a first name" });
this.lastName = ko.observable(last).extend({ required: "" });
}
ko.applyBindings(new AppViewModel("Bob","Smith"));
应用多个扩展程序
多个扩展器可以在对可观察者的.extended方法的单个调用中应用。
this.firstName = ko.observable(first).extend({ required: "Please enter a first name", logChange: "first name" });
在这种情况下,required和logChange扩展器都会对我们的observable执行。
KnockoutJS 3.X API 第七章 其他技术(2) 使用扩展器来增加可观察量(监控属性)的更多相关文章
- KnockoutJS 3.X API 第七章 其他技术(4) 速率限制
注意:这个速率限制API是在Knockout 3.1.0中添加的. 通常,更改的observable立即通知其订户,以便依赖于observable的任何计算的observable或绑定都会同步更新. ...
- KnockoutJS 3.X API 第七章 其他技术(8) 异步错误处理
注意:本文档适用于Knockout 3.4.0及更高版本. ko.onError Knockout包装内部异步调用,并在抛出原始错误之前查找可选的ko.onError回调以执行(如果遇到异常). 这使 ...
- KnockoutJS 3.X API 第七章 其他技术(7) 微任务
注意:本文档适用于Knockout 3.4.0及更高版本. Knockout的微任务队列 Knockout的微任务队列支持调度任务尽可能快地运行,同时仍然是异步的,努力安排它们在发生I / O,回流或 ...
- KnockoutJS 3.X API 第七章 其他技术(6) 使用“fn”添加自定义函数
有时,您可能会通过向Knockout的核心值类型添加新功能来寻找机会来简化您的代码. 您可以在以下任何类型中定义自定义函数: 因为继承,如果你附加一个函数到ko.subscribable,它将可用于所 ...
- KnockoutJS 3.X API 第七章 其他技术(5) 使用其他事件处理程序
在大多数情况下,数据绑定属性提供了一种干净和简洁的方式来绑定到视图模型. 然而,事件处理是一个常常会导致详细数据绑定属性的领域,因为匿名函数通常是传递参数的推荐技术. 例如: <a href=& ...
- KnockoutJS 3.X API 第七章 其他技术(3) 延迟更新
.example { display: inline-block; padding: 1em; margin-right: 2em; background: #F6F6EF; } 注意:本文档适用于K ...
- KnockoutJS 3.X API 第七章 其他技术(1) 加载和保存JSON数据
Knockout允许您实现复杂的客户端交互性,但几乎所有Web应用程序还需要与服务器交换数据,或至少将本地存储的数据序列化. 最方便的交换或存储数据的方式是JSON格式 - 大多数Ajax应用程序今天 ...
- KnockoutJS 3.X API 第六章 组件(3) 组件绑定
组件绑定将指定的组件注入到元素中,并且可选地将参数传递给它. 本节目录 一个例子 API 组件生命周期 备注1:仅限模板组件 备注2:使用没有容器元素的组件 备注3:将标记传递给组件 处置和内存管理 ...
- KnockoutJS 3.X API 第三章 计算监控属性(1) 使用计算监控属性
计算监控属性(Computed Observables) 如果你有一个监控属性firstName,和另一个lastName,你要显示的全名?可以使用计算监控属性来实现-它依赖于一个或多个其他监控属性, ...
随机推荐
- sql查询中datetime显示的格式为yyyy-DD-mm
datetime数据库中保存的形式为2008/9/29 星期一 上午 12:00:00,希望界面显示2008-09-29,则可以用到以下sql语句. ),kgrq, ),),jhjgrq, ),'/' ...
- 通用js地址选择器
用js实现通用的地址选择器,省份,城市,地区自动关联更新 点击下面查看详细代码: http://runjs.cn/code/s8sqkhcv 关键地址库代码: var addr_arr = new A ...
- 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)
题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...
- vim配置及快捷键
vim+python http://codingpy.com/article/vim-and-python-match-in-heaven/ vim+c++ http://jikaichen.com/ ...
- sublime插件
CnDict: 中英文字典软件,快捷键查词,目前支持金山词霸和有道词典. BracketHighlighter: 有个笑话,说前苏联间谍花了巨大的代价,偷到了阿波罗飞船的最后一屏的代码,发现全部是 } ...
- Asp.net 配置web.Config 在出错时跳转到相应页面
<!--<customErrors mode="On" defaultRedirect="error.aspx"> <erro ...
- MySQL中EXPLAIN命令详解
explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 使用方法,在select语句前加上explain就可以了: 如: expla ...
- JAVA使用SAX解析XML文件
在我的另一篇文章(http://www.cnblogs.com/anivia/p/5849712.html)中,通过一个例子介绍了使用DOM来解析XML文件,那么本篇文章通过相同的XML文件介绍如何使 ...
- JS中数组的操作[转]
1.数组的创建 var arrayObj = new Array(); //创建一个数组 var arrayObj = new Array([size]); //创建一个数组并指定长度,注意不是上限, ...
- 日常关键字:定时关机、该任务映像已损坏或已篡改.(0x80041321)、ChaZD生词同步扇贝
我在床上用chinanet网络慢得简直令人发指,12B/S.是的你没有看错,这是我最常看到的网速.但是我最近发现电脑联网开出一个WiFi,在床上用手机上网时,网速会一点提升,可达到1KB/S(⊙﹏⊙) ...