Knockout v3.4.0 中文版教程-6-计算监控-可写的计算监控
2.可写的计算监控
初学者可能想要跳过本节 - 可写的计算监控是相当高级的部分,在大多数情况下不是必需的。
通常,计算监控是一个通过其他监控值计算出的值,因此是只读的。 令人惊讶的是,可以使计算监控值变得可写。 你只需要提供自己的回调函数,输入一些正确的值。
你可以使用一个可写的计算监控,就像一个常规的监控对象,用你自己的逻辑来定义读写。就像一个监控对象一样,您可以使用链接语法将值写入模型对象上的对过监控对象或计算监控对象。 例如,
myViewModel.fullName('Joe Smith').age(50).
可写计算监控是一个强大的功能,可能在很多场景都能会用到。
1. 例子1:分解用户输入
回到经典的名+姓=姓名的例子,你可以把前面的例子中的fullName 计算监控变为可写,那样用户可以直接编辑全名,并且他们输入的内容将被解析并映射回到底层的firstName和lastName监控。 在本例中,write回调函数将传入的内容拆分为firstName和lastName两个部分,并将这些值传回底层的监控对象。
视图
<div>First name: <span data-bind="text: firstName"></span></div>
<div>Last name: <span data-bind="text: lastName"></span></div>
<div class="heading">Hello, <input data-bind="textInput: fullName"/></div>
视图模型
function MyViewModel() {
this.firstName = ko.observable('Planet');
this.lastName = ko.observable('Earth');
this.fullName = ko.pureComputed({
read: function () {
return this.firstName() + " " + this.lastName();
},
write: function (value) {
var lastSpacePos = value.lastIndexOf(" ");
if (lastSpacePos > 0) { // 忽略无内容
this.firstName(value.substring(0, lastSpacePos)); // 更新"firstName"的值
this.lastName(value.substring(lastSpacePos + 1)); // 更新"lastName"的值
}
},
owner: this
});
}
ko.applyBindings(new MyViewModel());
这跟Hello World示例完全相反,在这里,姓和名不可编辑,但组合的全名是可编辑的。
前面的视图模型代码演示了用于初始化计算的observable的单一参数语法。 有关可用选项的完整列表,请参阅computed observable引用。
2. 例子2:全选/全不选功能
当提供给用户一个可选择列表,通过一种方式来全选和取消全选是非常有用的。通过一个布尔值可以相当直观地表示是否所有项被选中。当该值设置为true会进行全选操作,false则取消全选。
视图
<div class="heading">
<input type="checkbox" data-bind="checked: selectedAllProduce" title="Select all/none"/> Produce
</div>
<div data-bind="foreach: produce">
<label>
<input type="checkbox" data-bind="checkedValue: $data, checked: $parent.selectedProduce"/>
<span data-bind="text: $data"></span>
</label>
</div>
视图模型
function MyViewModel() {
this.produce = [ 'Apple', 'Banana', 'Celery', 'Corn', 'Orange', 'Spinach' ];
this.selectedProduce = ko.observableArray([ 'Corn', 'Orange' ]);
this.selectedAllProduce = ko.pureComputed({
read: function () {
//仅仅在主数组里面的项被添加到被选中数组中的时候快速比较一下数量
return this.selectedProduce().length === this.produce.length;
},
write: function (value) {
this.selectedProduce(value ? this.produce.slice(0) : []);
},
owner: this
});
}
ko.applyBindings(new MyViewModel());
3. 例子3:值转换器
有时,您可能需要以不同于其底层存储的格式在屏幕上表示一个数据项。例如,您可能希望将价格存储为浮点值,但让用户使用货币符号和固定小数位数编辑它。您可以使用可写的计算监控将浮点值格式化为价格显示,将传入值转换回浮点值:
视图
<div>Enter bid price: <input data-bind="textInput: formattedPrice"/></div>
<div>(Raw value: <span data-bind="text: price"></span>)</div>
视图模型
function MyViewModel() {
this.price = ko.observable(25.99);
this.formattedPrice = ko.pureComputed({
read: function () {
return '$' + this.price().toFixed(2);
},
write: function (value) {
//去掉不需要的字符,然后转为浮点数,把原始数据写入底层价格监控对象
value = parseFloat(value.replace(/[^\.\d]/g, ""));
this.price(isNaN(value) ? 0 : value); //写入底层存储
},
owner: this
});
}
ko.applyBindings(new MyViewModel());
现在,每当用户输入新价格时,文本框将立即更新显示格式化为货币符号加两位小数的形式,无论他们输入什么格式的值。这提供了很棒的用户体验,因为用户看到软件已经将它们输入的数据理解为价格。他们知道他们不能输入多于两个小数位,因为如果他们尝试,额外的小数位将立即删除。类似地,它们不能输入负值,因为write回调函数会除去任何减号。
4. 例子4:过滤和验证用户输入
示例1展示了可写的计算监控如何有效地过滤传入的数据,如果它们不满足某些条件,则选择不将值传回底层监控对象。比如它忽略了不包含空格的全名值。
更进一步,您还可以根据最新输入是否有效来切换isValid标志,并在UI中显示相应地消息。有一个更简单的验证方法(后面解释),但首先考虑下面的例子,它演示了这个机制:
视图
<div>Enter a numeric value: <input data-bind="textInput: attemptedValue"/></div>
<div class="error" data-bind="visible: !lastInputWasValid()">That's not a number!</div>
<div>(Accepted value: <span data-bind="text: acceptedNumericValue"></span>)</div>
视图模型
function MyViewModel() {
this.acceptedNumericValue = ko.observable(123);
this.lastInputWasValid = ko.observable(true);
this.attemptedValue = ko.pureComputed({
read: this.acceptedNumericValue,
write: function (value) {
if (isNaN(value))
this.lastInputWasValid(false);
else {
this.lastInputWasValid(true);
this.acceptedNumericValue(value); // Write to underlying storage
}
},
owner: this
});
}
ko.applyBindings(new MyViewModel());
现在,acceptedNumericValue将只包含数字,输入的任何其他值将触发验证消息的出现,而不是更新acceptedNumericValue的值。
注意:对于验证输入是否是数字这样简单的需求,用这种技术是浪费的。 使用jQuery Validation在元素上验证是否是数字容易得多。Knockout和jQuery Validation会一起工作得很好,如网格编辑器示例所示。但是,上述示例演示了使用自定义逻辑进行过滤和验证来控制显示相关响应消息,这是一种更通用的机制,如果您的场景比jQuery验证处理本身更复杂,这可能是有用的。
Knockout v3.4.0 中文版教程-6-计算监控-可写的计算监控的更多相关文章
- Knockout v3.4.0 中文版教程-8-计算监控-纯计算属性
4.纯计算属性 纯计算监控在KO 3.2.0中开始引入,比大多数应用程序使计算监控有更大的性能提升和内存优化.这是因为在自身没有订阅的时候不会保持订阅状态.特性如下 阻止内存泄露 - 避免在应用程序里 ...
- Knockout v3.4.0 中文版教程-5-计算监控-使用计算监控
3. 计算监控 1.使用计算监控 如果你有一个监控的属性firstName和另一个lastName,但你想显示全名怎么办? 这就是引入计算监控的原因-这是依赖于一个或多个其他的observables函 ...
- Knockout v3.4.0 中文版教程-16-控制流-foreach绑定
2. 控制流 1. foreach绑定 目的 foreach绑定会遍历一个数组,为每个数组项生成重复的元素标记结构并做关联.这在渲染列表或表格的时候特别有用. 假设你的数组是一个监控数组,之后无论你进 ...
- Knockout v3.4.0 中文版教程-1-入门和安装
英文原版教程:http://knockoutjs.com/documentation/introduction.html 注:此教程根据英文原版翻译,仅作练习,如有不足或错误,请指正 说明: 对原文中 ...
- Knockout v3.4.0 中文版教程-9-计算监控-API参考
5.参考 下面的内容描述了如何构建和使用计算监控. 1. 构建一个计算监控 可以用如下的形式构建一个计算监控: ko.computed( evaluator [, targetObject, opti ...
- Knockout v3.4.0 中文版教程-7-计算监控-依赖跟踪如何工作
3.依赖跟踪如何工作 初学者不需要知道这一点,但更高级的开发人员将想知道为我们怎么实现KO自动跟踪依赖性和自动更新UI的正确部分... 它其实相当简单优雅,跟踪算法如下: 当你定义一个计算监控,KO立 ...
- Knockout v3.4.0 中文版教程-2-监控-通过监控创建视图模型(上)
2. 监控 1.通过监控创建视图模型 1. 监控 Knockout是基于以下三个核心特性: 监控和依赖跟踪 声明式绑定 模板 在本节,你将第一次了解这三个特性,在这之前,我们先来了解以下MVVM模式和 ...
- Knockout v3.4.0 中文版教程-14-控制文本内容和外观-style绑定
5. style绑定 目的 style绑定用来给关联的DOM元素添加或移除一个或多个样式值.在如下情况很有用,比如,当某些值为负时,高亮显示,或者设置容器元素的宽度来匹配数值的改变. (注意:如果你不 ...
- Knockout v3.4.0 中文版教程-13-控制文本内容和外观-css绑定
4. css绑定 目的 css绑定可以给关联的DOM元素添加或移除一个或多个CSS类.该绑定很有用,比如,当一些值为负数时高亮这些值为红色. (注意:如果你不想使用一个CSS类选择器来附加样式而想直接 ...
随机推荐
- HDU 3359 高斯消元模板题,
http://acm.hdu.edu.cn/showproblem.php?pid=3359 题目的意思是,由矩阵A生成矩阵B的方法是: 以a[i][j]为中心的,哈曼顿距离不大于dis的数字的总和 ...
- BIO,NIO,AIO总结
熟练掌握 BIO,NIO,AIO 的基本概念以及一些常见问题是你准备面试的过程中不可或缺的一部分,另外这些知识点也是你学习 Netty 的基础. BIO,NIO,AIO 总结 1. BIO (Bloc ...
- 遍历list集合的三种方式
List<String> list1 = new ArrayList<String>(); list1.add("1"); list1.add(" ...
- android开发学习 ------- android studio 同时用svn和git 进行代码管理 出现的问题
svn和git的工作机制: SVN 是集中式或者有中心式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活,干完后,需要 ...
- myBatis-类型关联
1.一对多 collection <resultMap id="deptsql" type="Dept"> <id column=" ...
- 使用Intellij IDEA搭建一个简单的Maven项目
IntelliJ IDEA是Java最优秀的开发工具,它功能全面,提示比较智能,开发界面炫酷,新技术支持的比较迅速. 我使用了Eclipse快10年了,IntelliJ IDEA这么好用必须要试一试. ...
- 简述UML类图
注:本文摘自刘伟老师的博客http://blog.csdn.net/lovelion/article/details/7838679,如有侵权,请联系本人! 1.类的UML图示 在UML中,类使用包含 ...
- Vue.js中data,props和computed数据
data data 是Vue实例的数据对象.Vue将会将data 的属性转换为 getter/setter, 也就是用Object.defineProperty方法(在官网里面有深入响应式原理里面具体 ...
- IE6下png背景不透明——张鑫旭博客读书笔记
从今天开始跟着大牛张鑫旭的步伐,每天进步一点点 问题:IE6不支持png背景透明或半透明 一.可解决的方法 补充:css滤镜主要是用来实现图像的各种特殊效果.(了解) css滤镜的标识符是“filte ...
- 从零开始利用vue-cli搭建简单音乐网站(六)
上一篇遗漏了一个简单的效果没写,见下图: 主页面点击热门推荐和更多之后跳转到歌曲列表页面,现在的页面只是简单的把所有歌曲列出来,没有进行排序.实现起来也很简单,在MainPage的两个链接上添加: & ...