.liveexample{
padding: 1em;
background-color: #eeeedd;
border: 1px solid #ccc;
max-width: 655px;
font-size:18px;

可赋值的计算监控属性

可赋值的计算监控属性是非常专业的,大多数情况下一般用不到,初学者可以跳过这一节

通常情况下,计算监控属性一般情况下是只读的。我们可以通过使用自己的回调函数让计算监控属性变为可赋值状态。

您可以用自己的定制逻辑让计算监控属性可写。就像将空属性,可以使用一个模型对象的链接的语法进行赋值。例如,myViewModel.fullName('Joe Smith').age(50)

示例1:分解用用户输入

让我们回到经典的例子“名+姓=全名”例如,fullName是计算监控属性,用户可以直接编辑全名,再根据用户输入的全名解析并将值分别赋值给firstName和lastName这两个监控属性。

First name:
Last name:
Hello,

UI源码:

<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());

本例中,使用了pureComputed(当然也可以使用Computed)的read和write回掉函数,其中write回掉函数将计算监控属性进行解析,并分别赋值给firstName和lastName这两个监控属性。

示例2:全选或取消全选项目

当使用复选框来选择项目的时候需要包括全选或取消全选的所有项目的方法。

Produce

UI源码:

<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 () {
// 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:值转换器

有时候,可能界面上的值并非是要传递到数据库中的值。例如,您可能希望存储原始浮点值,但是在用户编辑的时候让他跟一个货币符号。可以通过如下方式来进行转换:

Enter bid price:
(Raw value: 25.99)

UI源码:

<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) {
// 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());

现在,只要用户进入一个新的价格,文本框会立即更新,以显示货币符号和两位小数格式,这是一种很好的用户体验,就算用户多输入几位小数,多出两位小数的部分也会被自动删除。同样,它们不能输入负值,因为write回掉函数会去掉任何减号。

示例4:筛选和验证用户输入

在示例1中,描述了如何编写可赋值的计算监控属性,但是如果用户在不输入空格的情况下,将会出现LastName不被赋值的情况。

本例中,将使用KO的验证机制,保证在用户输入无效值的时候给出错误提示:

Enter a numeric value:
That's not a number!
(Accepted value: 123)

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将只包含数值,如果键入其他任何值都会触发一个验证消息,而不更新的UI界面的acceptedNumericValue

总结

对于上述示例,有些时候可能使用Jquery验证会更加简单便利,有些时候可能KO的计算监控属性验证更加简单,这需要你视情况而选择某种技术来解决问题。大多数新情况下都是配合KO和Jquery使用,上述示例只是描述一下KO的这些机制作用。切勿生搬硬套。要灵活运用。

KnockoutJS 3.X API 第三章 计算监控属性(2) 可赋值的计算监控属性的更多相关文章

  1. KnockoutJS 3.X API 第三章 计算监控属性(5) 参考手册

    计算监控属性构造参考 计算监控属性可使用以下形式进行构造: ko.computed( evaluator [, targetObject, options] ) - 这种形式是创建一个计算监控属性最常 ...

  2. KnockoutJS 3.X API 第三章 计算监控属性(1) 使用计算监控属性

    计算监控属性(Computed Observables) 如果你有一个监控属性firstName,和另一个lastName,你要显示的全名?可以使用计算监控属性来实现-它依赖于一个或多个其他监控属性, ...

  3. KnockoutJS 3.X API 第三章 计算监控属性(3) KO如何实现依赖追踪

    KO是如何实现自动更新的 初学者可以掠过该篇,如果你是一个刨根问底的开发者,那本节将告诉你KO是如何实现依赖追踪和UI自动更新的. 其实很简单,KO的依赖追踪算法如下: 当你声明一个计算监控属性,KO ...

  4. KnockoutJS 3.X API 第三章 计算监控属性(4)Pure computed observables

    Pure computed observables Pure computed observables是KO在3.2.0版本中推出的.她相对于之前的ComputedObservables有很多改进: ...

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

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

  6. ES6标准入门 第三章:变量的解构赋值

    解构赋值:从数组和对象中提取值,对变量进行赋值. 本质上,这种写法属于“匹配模式”:只要等号两边的模式相同,左边的变量就会被赋予对应的值. 1.数组的结解构赋值 基本用法 let [foo, [[ba ...

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

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

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

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

  9. KnockoutJS 3.X API 第六章 组件(4) 自定义元素

    自定义元素提供了一种将组件注入视图的方便方法. 本节目录 介绍 例子 传递参数 父组件和子组件之间的通信 传递监控属性的表达式 将标记传递到组件中 控制自定义元素标记名称 注册自定义元素 备注1:将自 ...

随机推荐

  1. sky简介

    sky简介 sky是一种构建高性能.跨平台手机APP的新的途径.更值得关注的是,sky是一种渲染引擎.脚本引擎.一个框架和一系列的材料设计模式的窗体组件.sky是当前以及未来手机APP的一种优化手段. ...

  2. Tomcat实现分析(一)--类加载及容器组件

    启动脚本 启动命令中的参数如下: org.apache.catalina.startup.Bootstrap start -Djava.util.logging.config.file=/opt/ap ...

  3. poj 2482 Stars in Your Window (线段树:区间更新)

    题目链接:http://poj.org/problem?id=2482 读完题干不免有些心酸(

  4. Freemarker 内置函数 数字、字符串、日期格式化用法介绍

    在用FreeMarker过程中,感觉FreeMarker的字符串,日期,集合等处理能力还是很强大的,上网搜了一些资料,整理如下,以便能帮助大家更熟练的应用Freemarker完成项目开发. 一.Seq ...

  5. 转载:JProfiler远程监控LINUX上的Tomcat过程细讲

    来源于xuwanbest的博客   所谓"工欲善其事,必先利其器",好的工具确能起到事半工倍的作用.我用到的最多的就两个JConsole 和JProfiler .JConsole监 ...

  6. AndroidManifest.xml中<activity></activity>相关属性说明

    虽说,从事android开发有一定时间了,对于Activity大家也都不陌生,但是具体的对于Activity中相关属性的含义有必要做一个系统的总结: intent-filteraction: 来指定响 ...

  7. c++的转换

    1.静态转换 static_cast 用于明确定义的变换 ,包括 编译器允许的非强制转换和不太安全但定义清楚的变换.ps:(非强制变换,窄化变换,隐式转换,类层次静态定位,void*强制转换) 2.常 ...

  8. .Net Core下如何管理配置文件

    一.前言 根据该issues来看,System.Configuration在.net core中已经不存在了,那么取而代之的是由Microsoft.Extensions.Cnfiguration.XX ...

  9. Jexus 5.8.2 Beta1发布:为Asp.Net Core进入生产环境提供平台支持

    Jeuxs 5.8.2beta1于7月10日正式发布. 有如下更新: 1,为FastCGI提供KEEP_CONN支持,优化FastCGI工作线程池调度算法: 2,完善反向代理的负载均衡策略,支持“随机 ...

  10. 剑英陪你玩转图形学(五)focus

    很久没来和大家交流业务(zhuangbi)水平了,最近实在是很忙,报名了小游戏大赛,一点时间都抽不出,已经坑了. 今天抓紧时间和大家介绍一个小效果: 新手引导的时候,我们会需要一种全屏幕黑掉,只有一个 ...