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类选择器来附加样式而想直接 ...
随机推荐
- c#学习系列之字段(静态,常量,只读)
C#静态变量使用 static 修饰符进行声明,在类被实例化时创建,通过类进行访问不带有 static 修饰符声明的变量称做非静态变量.static变量在对象被实例化时创建,通过对象进行访问一个类的所 ...
- 简单了解junit的使用
普通使用: 在没有用测试框架之前,我们要用一个main方法来跑代码,而有了像junit这样的测试框架后,就可以不用次次写个main方法了. 直接上代码,注释里有说明: package com.stuP ...
- 关于如何在其他包中写controller和简单介绍@SpringBootApplication
本文参考博客:https://blog.csdn.net/u013473691/article/details/52353923 关于@Configuration和@Bean参考博客:https:// ...
- RTT
Segger RTT的使用 一般arm系统中,如何通过电脑键盘和显示器同mcu进行交互最有效的有两种形式:arm7的semihost,cm时代的traceswo.现在jlink推出了颇具特色的rtt( ...
- Redis基础理论
一.概述 二.数据类型 STRING LIST SET HASH ZSET 三.数据结构 字典 跳跃表 四.使用场景 计数器 缓存 查找表 消息队列 会话缓存 分布式锁实现 其它 五.Redis 与 ...
- EDAS提交论文字体未嵌入
一.深夜更一波,刚刚在EDAS提交论文,提示格式不通过,说我有字体未嵌入.但是之前一直都没有问题,这次只是在LaTeX中嵌图的时候把eps换成PDF了.所以问题应该是出在我的PDF图里,里面有字体未被 ...
- JavaScriptSerializer类序列化日期时需要注意的问题
1.让我们来看看使用JavaScriptSerializer类序列化日期会出现什么问题? 1)创建用于序列化的测试类,如下: public class Person { public int ID { ...
- Vue.js - day7
使用mui的tab-top-webview-main完成分类滑动栏 兼容问题 和 App.vue 中的 router-link 身上的类名 mui-tab-item 存在兼容性问题,导致tab栏失效, ...
- 2189 数字三角形W
2189 数字三角形W 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题目描述 Description 数字三角形要求走到最后mod 100最大 输入描述 ...
- 自定义消息中如果需要定义WPARAM和LPARAM,该怎么使用和分配?
写Windows程序不可避免要使用自定义的消息,也就是从WM_USER开始定义的消息.在定义一个消息后,往往我们还要定义针对该消息的WPARAM甚至是LPARAM.WPARAM和LPARAM是什么,可 ...