可写的计算监控(Writable computed observables)
新手可忽略此小节,可写依赖监控属性真的是太advanced了,而且大部分情况下都用不到。
一般情况下,计算监控的值是通过其他监控属性的值计算出来的,因此它是只读的。这个看似很奇怪,我们有什么办法可以让他变成可写的吗。 此时,我们只需要提供一个callback的函数就可以做到。
通过你自定义的逻辑拦所有的读写操作,你可以像使用其他监控属性一样使用计算监控属性。类似obeservables一样,你可以一次改变多个observable或者computered observable属性的值,通过以下这种方式:
myViewModel.fullName('Joe Smith').age(50).
可写的计算监控属性在某些场景下将会是一个非常有用的特性。
示例1:分解用户输入
返回到经典的“first name + last name = full name” 例子上,你可以让事情调回来看: 让依赖监控属性fullName可写,让用户直接输入姓名全称,然后输入的值将被解析并映射写入到基本的监控属性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) { // Ignore values with no space character
this.firstName(value.substring(0, lastSpacePos)); // Update "firstName"
this.lastName(value.substring(lastSpacePos + 1)); // Update "lastName"
}
},
owner: this
});
}
ko.applyBindings(new MyViewModel());
这是一个Hello World 例子的反例子,姓和名都不可编辑,相反姓和名组成的姓名全称却是可编辑的。
上面的view model演示的是通过一个简单的参数来初始化计算监控属性(computed observables)。详细的参数说明请参见computed observable reference。
示例2:全选/反选所有项
当呈现给用户一系列可选择的项时,我们通常会提供全选和反选的功能。这时,可以使用一个bool值来比较直观的表示是否是全选或者是反选。当返回True时表示选择了所有项,当返回false时表示反选。

HTML:
<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>
view model:
function MyViewModel() {
this.produce = [ 'Apple', 'Banana', 'Celery', 'Corn', 'Orange', 'Spinach' ];
this.selectedProduce = ko.observableArray([ 'Corn', 'Orange' ]);
this.selectedAllProduce = ko.pureComputed({
read: function () {
// Comparing length is quick and is accurate if only items from the
// main array are added to the selected array.
return this.selectedProduce().length === this.produce.length;
},
write: function (value) {
this.selectedProduce(value ? this.produce.slice(0) : []);
},
owner: this
});
}
ko.applyBindings(new MyViewModel());
示例3:value转换器
有时候你可能需要显示一些不同格式的数据,从基础的数据转化成显示格式。比如,你存储价格为float类型,但是允许用户编辑的字段需要支持货币单位和小数点。你可以用可写的计算监控属性来实现,然后解析传入的数据到基本 float类型里:
HTML:
<div>Enter bid price: <input data-bind="textInput: formattedPrice"/></div>
<div>(Raw value: <span data-bind="text: price"></span>)</div>
view model:
function MyViewModel() {
this.price = ko.observable(25.99);
this.formattedPrice = ko.pureComputed({
read: function () {
return '$' + this.price().toFixed(2);
},
write: function (value) {
// Strip out unwanted characters, parse as float, then write the
// raw data back to the underlying "price" observable
value = parseFloat(value.replace(/[^\.\d]/g, ""));
this.price(isNaN(value) ? 0 : value); // Write to underlying storage
},
owner: this
});
}
ko.applyBindings(new MyViewModel());
这样,当用户输入一个新的价格时,无论用户输入的是什么格式,text box就会将会将它格式化成货币符号并且只有两位小数。这样的用户体验就比较好。当用户输入了超过两位小数的数据时,系统就会自动舍弃多余的小数,只保留两位,然后用户就会知道不可以输入超过两位小数的值。同样,也不可以输入负数,因为系统会自动把负号去掉。
示例4:过滤并验证用户的输入
例1展示的是写操作过滤的功能,如果你写的值不符合条件的话将不会被写入,忽略所有不包括空格的值。
再多走一步,你可以声明一个监控属性isValid 来表示最后一次写入是否合法,然后根据真假值显示相应的提示信息。其他还有更简单的方法来做全法性验证(后面再介绍),先看下面的示例:
HTML:
<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>
View Model:
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。
备注:上面的例子显得杀伤力太强了,更简单的方式是在<input>上使用jQuery Validation和number class。Knockout可以和jQuery Validation一起很好的使用,参考例子:grid editor。当然,上面的例子依然展示了一个如何使用自定义逻辑进行过滤和验证数据,如果验证很复杂而jQuery Validation很难使用的话,你就可以用它。
可写的计算监控(Writable computed observables)的更多相关文章
- Knockout v3.4.0 中文版教程-6-计算监控-可写的计算监控
2.可写的计算监控 初学者可能想要跳过本节 - 可写的计算监控是相当高级的部分,在大多数情况下不是必需的. 通常,计算监控是一个通过其他监控值计算出的值,因此是只读的. 令人惊讶的是,可以使计算监控值 ...
- 使用计算监控(Using computed observables)
计算监控(Computed Observables) 如果有两个监控属性firstName, lastName,此时我们要显示full name,我们要怎么办呢? 这时,可以创建一个computed ...
- KnockoutJS 3.X API 第三章 计算监控属性(1) 使用计算监控属性
计算监控属性(Computed Observables) 如果你有一个监控属性firstName,和另一个lastName,你要显示的全名?可以使用计算监控属性来实现-它依赖于一个或多个其他监控属性, ...
- Knockout 新版应用开发教程之Computed Observables
Computed Observables 如果你有监控属性firstName和lastName的话,此时如果你想要显示全名? 这个时候computed(以前叫做依赖)监控属性就出马了,这是一个函数用来 ...
- KnockoutJS 3.X API 第三章 计算监控属性(4)Pure computed observables
Pure computed observables Pure computed observables是KO在3.2.0版本中推出的.她相对于之前的ComputedObservables有很多改进: ...
- 纯计算监控(Pure computed observables)
纯计算监控,在knockout 3.2.0里才有,提供了对性能和内存更好的管理.这是因为纯计算监控不包含对他的依赖的订阅.特点有: 防止内存泄漏 降低计算开销:值不再是observed,是一个不会重新 ...
- KnockoutJS 3.X API 第三章 计算监控属性(5) 参考手册
计算监控属性构造参考 计算监控属性可使用以下形式进行构造: ko.computed( evaluator [, targetObject, options] ) - 这种形式是创建一个计算监控属性最常 ...
- Knockout v3.4.0 中文版教程-5-计算监控-使用计算监控
3. 计算监控 1.使用计算监控 如果你有一个监控的属性firstName和另一个lastName,但你想显示全名怎么办? 这就是引入计算监控的原因-这是依赖于一个或多个其他的observables函 ...
- KnockoutJS 3.X API 第三章 计算监控属性(2) 可赋值的计算监控属性
.liveexample{ padding: 1em; background-color: #eeeedd; border: 1px solid #ccc; max-width: 655px; fon ...
随机推荐
- Symfony官方视频教程
视频获取方式,添加Symfony学习群,在群文件中获取,QQ群182983780
- js生成缩略图后上传并利用canvas重绘
function drawCanvasImage(obj,width, callback){ var $canvas = $('<canvas></canvas>'), can ...
- git add -f
git add -f 添加已被 .gitignore 忽略的文件/文件夹
- 关于ajax的短轮询问题
利用前台的ajax不断向后台服务器请求,后台服务器不断查看数据库里的信息是否变化.若变化将信息返回前台,并执行一些操作 前台ajax代码 注意要加上cache这一项,如果是post请求的化,可以免了. ...
- URLEncode编码和URLDecode解码
String text1 = java.net.URLEncoder.encode("中国" ,"utf-8" ); String text2 = java.n ...
- nyoj 523 双向广搜
题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=523 #include<iostream> #include<cstd ...
- Oracle 中的Top写法
由于Oracle不支持select top 语句,所以在Oracle中经常是用order by 跟rownum的组合来实现select top n的查询.简单地说,实现方法如下所示:select 列名 ...
- Error(10028)
两个进程里都有同一个条件判断的话,会产生并行信号冲突的问题. 同一个信号不允许在多个进程中赋值,否则则为多驱动. 进程的并行性决定了多进程不同能对同一个对象进行赋值.
- Unity3D研究院之在把代码混淆过的游戏返混淆回来(七十七)
最近一直在找如何在MAC上混淆Android的DLL,至今没能找到合适的,有大神知道记得告诉我喔.今天群里有人说了一个混淆代码和返混淆代码的工具de4dot ,不查不知道一查吓一跳.这玩意可以把别人混 ...
- 第七十八节,CSS3文本效果
CSS3文本效果 一.文本阴影 CSS3提供了text-shadow文本阴影效果,这个属性在之前讲过,只是没有涉及浏览器 支持情况. 浏览器支持情况 text-shadow Opera ...