knockout 学习笔记

1、激活knockout
ko.applayBindings()
第一个参数是激活ko时用于声明绑定的View Model的对象
(myViewModel= {personName: 'Bob',personAge: 123})
第二个参数是可选的,用于设置要使用data-bind属性的html元素或容器
(ko.applayBindings(myViewModel, documentElementById("id")))
比如:ko.applyBindings(myViewModel);

2、observables(响应一个对象)
当view model发生变化时,能够自动更新ui界面
将model属性声明成observable
(myViewModel= {personName: ko.observable('Bob'),personAge: ko.observable(123)})
页面上如果要和一个输入框绑定起来的话,

<input data-bind="value: personName"/>
<span data-bind="text: personName"></span>

读取observable属性:myViewModel.personName()

设置observable属性:myViewModel.personName(""Mary"")

同时设置多个observable属性:myViewModel.personName(""Mary"").personAge(50) 链式语法

3、observableArray(响应一个对象的集合)

var myObservableArray = ko.observableArray(); // 实例化一个数组
myObservableArray.push('Some value'); // 向数组中添加记录
myObservableArray.push('Some value');

==》Knockoutjs数组常用的方法如下
(1)myObservableArray.push('Some new value'):增加一个新的元素

(2)myObservableArray.pop():删除一个元素,并返回其值

(3)myObservableArray.unshift('Some new value'):在数组的开始处增加一个新的元素

(4)myObservableArray.shift():删除数组的第一个元素,并返回其值

(5)myObservableArray.reverse():反转数组的顺序

(6)myObservableArray.sort():数组排序。排序规则可以由用户自己定义也可以使用默认,
默认情况下按照字母顺序或者数字的顺序进行排序。自己定义排序规则时需要接收数组 中的两个元素,
并且需要返回一个数值,当此值小于0时表示第一个元素较小,当此值大于0时,表示第二个元素较小,
当等于0时表示两个元
myObservableArray.sort(function(left, right) {
return left.lastName == right.lastName ? 0 : (left.lastName &lt; right.lastName ? -1 : 1)
})
(7)myObservableArray.splice():数组截取。例如:myObservableArray.splice(1, 3),代表从数组的第一个元素开始,截取三个元素,并且将他们作为数组返回。
(8)myObservableArray().length():数组的长度
(9)myObservableArray()[0]:取得数组的第一个值
(10)myObservableArray.remove(someItem)移除myObservableArray数组内所有匹配someItem的对象, 并把这些对象组成一个数组返回
(11)myObservableArray.remove(function(item) { return item.age < 18 })移除myObservableArray数组内所有年龄属性小于18的对象,并返回这些对象组成的新数组
(12)myObservableArray.removeAll(['Chad', 132, undefined])移除myObservableArray数组内所有匹配'Chad',123, orundefined 的对象并把它们组成新数组返回
(13)myObservableArray.removeAll()移除myObservableArray数组内所有数据,并返回这些数据组成的一个新数组
然则基于下述来由,凡是推荐应用KO中的等价办法:

(14)KO中的办法支撑所有主流浏览器(比如,Javascript原生办法indexOf在<=IE8时不正常,而KO的indexOf 能正常工作)
(15)dependency tracking
(16)语法加倍简洁:调用KO中的办法应用myObservableArray.push(...),调用原生Javascript中的办法应用myObservableArray().push(...)

4、computed(计算属性,依赖一个或者多个属性)

法一:
function AppViewModel(){
this.fullName=ko.computed(function(){
return this.firstName()+" "+this.lastName();
},this);
}
法二:(流行)
function AppViewModel(){
var self=this;
self.firstName=ko.observable('Bob');
self.lastName=ko.observable('Smith');
self.fullName=ko.computed(function(){
return self.firstName()+" "+self.lastName();
});
}
绑定到html上:
data-bind="text: fullName"

5、依赖链工作
(1)用items监控属性来代表一组items项

(2)另外一个selectedIndexes监控属性来用户已选择项目的索引

(3)一个selectedItems依赖属性来返回一组用户已选择的Item对象

(4)另外一个依赖属性来返回true或者false,来表示selectedItems中是否包含一些属性(如新的或尚未保存的)。一些UI元素,比如一个按钮可以基于此值来控制其启用或禁止。

然后,当改变items或者selectedIndexes都会影响到所有的依赖属性链,然后依次更新到绑定了这些项的UI。非常的整洁和优雅。

6、可写的计算属性==》提供一个回调函数来实现值的写入
(1)分解用户输入
比如:// 这里全名是可以写入的,但是firstName和lastName是不可写入的

function MyViewModel() {
this.firstName = ko.observable('Planet');
this.lastName = ko.observable('Earth');
this.fullName = ko.computed({
read: function () { },
write: function (value) {
varlastSpacePos = 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());

<p>Firstname:<span data-bind="text: firstName"></span></p>
<p>Lastname:<span data-bind="text: lastName"></span></p>
<h2>Hello,<input data-bind="value: fullName"/>!</h2>

(2)值转换

function MyViewModel1() {
this.price = ko.observable(25.99);
this.formattedPrice = ko.computed({
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 MyViewModel1());

<input data-bind="value: formattedPrice"/>

(3)筛选和验证用户输入 ==》监控属性isValid来表示最后一次写入是否合法,然后根据真假值显示相应的提示信息

function MyViewModel2() {
this.acceptedNumericValue = ko.observable(123);
this.lastInputWasValid = ko.observable(true);
this.attemptedValue = ko.computed({
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 MyViewModel2());

<p>Enter a numeric value:<input data-bind="value: attemptedValue"/></p>
<div data-bind="visible: !lastInputWasValid()">That's not a number!</div>
<div data-bind="visible: lastInputWasValid()">That's a number!</div>

7、确定一个属性是不是依赖属性
ko.isComputed()

8、依赖属性参考
一个依赖属性可以通过以下方式实现:

(1)ko.computed( evaluator [, targetObject, options] )这是用于创建依赖属性的一种最常见的方式。

evaluator--用于计算一个依赖属性当值的方法

targetObject--如果给定,当KO调用回调函数时,定义一个值表示

this--参阅管理”this”来了解更多信息。

options--依赖属性的参数对象。可以参看下面详细的清单。

(2)ko.computed( options )--单一参数方式接受一个JavaScript对象或者以下任意属性来创建一个依赖属性

read--必需参数,传入方法。用于运算当前依赖属性当前值的方法。

write–可选参数,传入方法。如果给定,将会使依赖属性可写这个方法接收一个外部的值来写入到依赖属性中。它通常是使用你自己定义的逻辑来处理传入的值,通常将值写入到相关的监控属性中。

owner–可选参数,传入对象。

传入的对象作为this的关键字在KO调用read和write方法使用。

deferEvaluation–可选参数,传入ture或者false。如果设置为true,则依赖属性的值直到有实际访问它之前它的值是不会重新计算的。默认情况下,依赖属性的值在创建过程中就已经初始化了。

disposeWhen–可选参数,传入方法。如果给出,该传入方法将会在每一次运算结束之后被调用来释放依赖属性。真正的结果就是触发依赖属性的disposal方法。

disposeWhenNodeIsRemoved–可选参数,传入方法。如果给出,当指定的DOM元素被KO删除的时候依赖属性的disposal方法会被触发。当元素的绑定被模版或者控制流程绑定方法移除的时候,此功能是用来释放依赖属性。

依赖属性提供了以下方法:

dispose()–释放依赖属性,清除所有的依赖订阅。此方法非常有用,当你想停止一个依赖属性以避免其更新或者清除一个内存中的依赖属性而那些存在依赖关系的监控值是不会被清除的。

extend(extenders)–用于扩展依赖属性。

getDependenciesCount()–返回依赖属性当前依赖关系数量。

getSubscriptionsCount()–返回依赖属性当前订阅数量(无论是其他的依赖属性或手动订阅)。

isActive ()–返回依赖属性在以后是否会被更新,一个依赖属性如果没有依赖关系是无效的。

peek ()–返回当前依赖属性的值而无需创建依赖关系(可以参考peek)。

subscribe( callback [,callbackTarget, event] )–注册一个手动订阅来通知依赖属性的变化。

9、数据绑定
数据绑定有三种方式:
One-Time(一次绑定)
One-Way(单向绑定)当viewModel发生变化时,ui也会随之变化
Two-way(双向绑定)这是最灵活的数据绑定,也是代价最大的


11、注册自己的订阅来通知监控属性的变化

var subscription = myViewModel.personName.subscribe(function(newValue) {
console.info("The person's new name is " + newValue);
});

12、终止自己的订阅:首先获取到这个订阅,然后调用dispose 方法即可。

subscription.dispose();

13、visable==>用来控制DOM元素的显示和隐藏
如果参数是一个observable值,visible绑定使得元素的visible状态随着参数值的变化而变化。
如果参数不是observable值,visible绑定仅仅会设置元素visible状态一次,以后不会再更新。

var viewModel = {
shouldShowMessage: ko.observable(true) // Message initially visible
};
viewModel.shouldShowMessage(false); // ... now it's hidden
viewModel.shouldShowMessage(true);
ko.applyBindings(viewModel);

<div data-bind="visible: shouldShowMessage">
You will see this message only when "shouldShowMessage" holds a true value.
</div>

也可以使用函数或者表达式来控制元素的显示和隐藏

var viewModel = {
myValues: ko.observableArray([]) // Initially empty, so message hidden
};
viewModel.myValues.push("some value"); // Now visible
ko.applyBindings(viewModel);

<div data-bind="visible: viewModel.myValues().length > 2, text: viewModel.myValues()[0]"> </div>

14、text绑定:通常情况下,该绑定在<span>和<em>这样的元素上非常有用,而实际上你可以绑定任何元素。
(1) 是用函数或者表达式来决定text值

var viewModel = {
price: ko.observable(24.95)
};
viewModel.priceRating = ko.computed(function() {
return this.price() > 50 ? "expensive" : "affordable";
}, viewModel);
ko.applyBindings(viewModel);

<span data-bind="text: priceRating"></span>

但是如果不需要创建计算属性的话,可以直接使用:
<span data-bind="text: price() >50 ? 'expensive' : 'affordable'"></span>

(2) 关于html编码
如果直接使用:viewModel.myMessage("<i>Hello, world!</i>");不会显示一个斜体文本,会按远洋标签进行输出

(3)使用“text”而没有一个容器元素
有时你可能需要使用Knockout在不使用多余的元素的情况下通过text绑定来设置文本内容。例如,在option元素中是不允许存在其他元素的,所以下面的绑定是无法正常工作的。
<select data-bind="foreach: items">
<option>Item<span data-bind="text: name"></span></option>
</select>
为了解决这个问题,你可以使用容器语法,它基于一个注释元素。
<select data-bind="foreach: items">
<option>Item<!--ko text: name--><!--/ko--></option>
</select>
<!--ko-->和<!--/ko-->注释标记作为起始和结束符,定义一个“虚拟元素”,里面包含了标记,Knockout能够识别这种虚拟元素语法和绑定作为你需要的容器元素而存在。

15、html绑定
KO设置该参数值到元素的innerHTML属性上,元素之前的内容将被覆盖。
如果参数是监控属性observable的,那元素的内容将根据参数值的变化而更新,如果不是,那元素的内容将只设置一次并且以后不在更新。
如果你传的是不是数字或者字符串(例如一个对象或者数组),那显示的文本将是yourParameter.toString()的等价内容。
ps: 因为该绑定设置元素的innerHTML,你应该注意不要使用不安全的HTML代码,因为有可能引起脚本注入攻击。如果你不确信是否安全(比如显示用户输入的内容),
那你应该使用text绑定,因为这个绑定只是设置元素的text 值innerText和textContent。

var viewModel = {
details: ko.observable() // Initially blank
};
viewModel.details("<em>For further details, view the report <a href='report.html'>here</a>.</em>");
ko.applyBindings(viewModel);

<div data-bind="html: details"></div>

16、css类名绑定
ps: 如果你想使用my-class class,你不能写成这样:
<div data-bind="css: { my-class: someValue }">...</div>
要这样写:
<div data-bind="css: { 'my-class': someValue }">...</div>

var viewModel = {
currentProfit: ko.observable(150000) // 如果大于0则删除这个CSS class
};
当currentProfit 小于0的时候,添加profitWarning CSS class到元素上,
viewModel.currentProfit(-50);

17、style属性绑定
注:应用的style的名字不是合法的JavaScript变量命名
如果你需要应用font-weight或者text-decoration,你不能直接使用,而是要使用style对应的JavaScript名称。
错误:{ font-weight: someValue }; 正确:{ fontWeight: someValue }
错误:{ text-decoration: someValue }; 正确:{ textDecoration: someValue }

var viewModel = {
currentProfit: ko.observable(150000)
};
viewModel.currentProfit(-50);
ko.applyBindings(viewModel);

<div data-bind="style: { color: currentProfit() < 0 ? 'red' : 'black' }">123</div>

18、attr属性绑定
注:应用的属性名字不是合法的JavaScript变量命名,比如属性名称是data-something的话,要记得加引号

var viewModel = {
url: ko.observable("year-end.html"),
details: ko.observable("Report including final year-end statistics")
};
ko.applyBindings(viewModel);

<a data-bind="attr: { href: url, title: details }">
Report
</a>

19、forEach绑定
(1)循环遍历输出某个数组、集合中的内容

var viewModel = {
people: [
{ firstName: 'Bert', lastName: 'Bertington' },
{ firstName: 'Charles', lastName: 'Charlesforth' },
{ firstName: 'Denise', lastName: 'Dentiste' }
],
}
ko.applyBindings(viewModel);

<select data-bind="foreach: people">
<option data-bind="text: firstName"></option>
</select>

(2)动态增加和删除遍历节点
其中: $index: 获得当前项的位置,从0开始
$parent: 指代this,当前 绑定的模型数据 的 父模型数据.
$parentContext 指 当前 绑定的模型数据 的父模型数据的上下文.

function AppViewModel() {
var self = this;

self.people = ko.observableArray([
{ name: 'Bert' },
{ name: 'Charles' },
{ name: 'Denise' }
]);

self.addPerson = function () {
self.people.push({ name: "New at " + new Date() });
};

self.removePerson = function () {
self.people.remove(this);
}
}
ko.applyBindings(new AppViewModel());

<ul data-bind="foreach: people">
<li>
Name at position <span data-bind="text: $index"> </span>:
<span data-bind="text: name"> </span>
<a href="#" data-bind="click: $parent.removePerson">Remove</a>
</li>
</ul>
<button data-bind="click: addPerson">Add</button>


(3)$data: 输出数组中的所有元素

ko.applyBindings({
months: ['Jan', 'Feb', 'Mar', 'etc']
});

<ul data-bind="foreach: months">
<li>
The current item is: <b data-bind="text: $data"></b>
</li>
</ul>

(4)使用"as"为foreach中的元素定义别名,即使用as来为我们要遍历的元素起一个别名

var viewModel = {
categories: ko.observableArray([
{ name: 'Fruit', items: ['Apple', 'Orange', 'Banana'] },
{ name: 'Vegetables', items: ['Celery', 'Corn', 'Spinach'] }
])
};
ko.applyBindings(viewModel);

<ul data-bind="foreach: { data: categories, as: 'category' }">
<li>
<ul data-bind="foreach: { data: items, as: 'item' }">
<li>
<span data-bind="text: category.name"></span>:
<span data-bind="text: item"></span>
</li>
</ul>
</li>
</ul>

(5)在没有绑定属性的情况下使用foreach
我们就没有一个可以绑定foreach的元素,此时我们可以通过以下的代码来实现:
ps: 使用<!--ko--><!--/ko-->来表示循环的开始和结束,这是一个虚拟的标签,
Knockoutjs能够对其中的foreach进行绑定就好像你将foreach绑定到了一个真实的标签上一样。

ko.applyBindings({
myItems: ['A', 'B', 'C']
});

<ul>
<li class="header">Header item</li>
<!-- ko foreach: myItems -->
<li>Item <span data-bind="text: $data"></span></li>
<!-- /ko -->
</ul>

(6)默认不显示被标示为删除的元素
有的时候我们要跳过数组中的一些元素,此时这些元素已经被标示为删除,
但并没有被真实删除,这些元素当我们使用foreach输出的时候是默认不显示的,
如果我们想要这些元素显示的话,我们可以使用includeDestroyed这个选项,比如:

<div data-bind='foreach: { data: myArray, includeDestroyed: true }'>
</div>

19、if binding 和 if not binding ==》 data-bind="if" / data-bind= "checked"
ps: 使用if是真正的控制html是否出现在DOM中,会修改dom结构,出于性能的考虑,不应该频繁修改if的绑定值

使用if binding可以控制某个组件动态显示,类似我们之前接触到的visible属性,不过此属性绑定过以后就不能更改,
而if binding可以根据相应的条件控制组件是否显示

ko.applyBindings({
displayMessage: ko.observable(true)
});

<label><input type="checkbox" data-bind="checked: displayMessage" /> Display message</label>
<div data-bind="if: displayMessage">Here is a message. Astonishing.</div>

也可以使用if来判断某个元素是否为null,如果为null则不会显示

ko.applyBindings({
planets: [
{ name: 'Mercury', capital: null },
{ name: 'Earth', capital: { cityName: 'Barnsley'} }
]
});

<ul data-bind="foreach: planets">
<li>
Planet: <b data-bind="text: name"> </b>
<div data-bind="if: capital">
Capital: <b data-bind="text: capital.cityName"> </b>
</div>
</li>
</ul>

20、with binding==》使用with binding来重新定义一个上下文绑定

使用coords下的latitude和longitude的时候我们就不需要使用
coords.latitude来调用了,因为我们使用with:coords来指定了coords的上下文,当我们使用coords下面的属性时就可以直接使用了

ko.applyBindings({
city: "London",
coords: {
latitude: 51.5001524,
longitude: -0.1262362
}
});
<h1 data-bind="text: city"> </h1>
<p data-bind="with: coords">
Latitude: <span data-bind="text: latitude"> </span>,
Longitude: <span data-bind="text: longitude"> </span>
</p>

==》动态交互的例子==》没懂

<form data-bind="submit: getTweets">
Twitter account:
<input data-bind="value: twitterName" />
<button type="submit">Get tweets</button>
</form>

<div data-bind="with: resultData">
<h3>Recent tweets fetched at <span data-bind="text: retrievalDate"> </span></h3>
<ol data-bind="foreach: topTweets">
<li data-bind="text: text"></li>
</ol>

<button data-bind="click: $parent.clearResults">Clear tweets</button>
</div>

<script type="text/javascript">
function AppViewModel() {
var self = this;
self.twitterName = ko.observable('@StephenFry');
self.resultData = ko.observable(); // No initial value

self.getTweets = function () {
twitterApi.getTweetsForUser(self.twitterName(), function (data) {
self.resultData({
retrievalDate: new Date(),
topTweets: data.slice(0, 5)
});
});
}

self.clearResults = function () {
self.resultData(undefined);
}
}

ko.applyBindings(new AppViewModel());
</script>

21、click事件
(1)不带参

var viewModel = {
numberOfClicks: ko.observable(0),
incrementClickCounter: function() {
var previousCount = this.numberOfClicks();
this.numberOfClicks(previousCount + 1);
}
};
ko.applyBindings(viewModel);

<div>
You've clicked
<span data-bind="text: numberOfClicks">
</span>
times
<button data-bind="click: incrementClickCounter">
Click me
</button>
</div>

(2)传参数给你的click 句柄 ==》传一个function包装的匿名函数

var viewModel = {
myClickFunction: function(opts) {
console.info(opts)
}
};
ko.applyBindings(viewModel);

<button data-bind="click: function() { viewModel.myClickFunction('ccl')}">
Click me 带参
</button>

(3)访问事件源对象

var viewModel = {
myFunction: function(event) {
if (event.shiftKey) {
//do something different when user has shift key down
} else {
//do normal action
}
}
};

如果需要的话,可以使用匿名函数的第一个参数传进去,然后在里面调用:

<button data-bind="click: function(event) { viewModel.myFunction(event, 'param1') }">
Click me
</button>

(4)允许执行默认事件
默认情况下,Knockout会阻止冒泡,防止默认的事件继续执行。例如,如果你点击一个a连接,在执行完自定义事件时它不会连接到href地址。这特别有用是因为你的自定义事件主要就是操作你的view model,而不是连接到另外一个页面。
当然,如果你想让默认的事件继续执行,你可以在你click的自定义函数里返回true。

(5)控制this句柄
KO在调用你定义的函数时,会将view model传给this对象(也就是ko.applyBindings使用的view model)。主要是方便你在调用你在view model里定义的方法的时候可以很容易再调用view model里定义的其它属性。
如果你想引用其它对象,我们有两种方式:
你可以和(2)里那样使用匿名函数,因为它支持任意JavaScript 对象。
你也可以直接引用任何函数对象。你可以使用bind使callback函数设置this为任何你选择的对象。例如:

<button data-bind="click: someObject.someFunction.bind(someObject)">
Click me
</button>

(6)防止事件冒泡clickBubble: false
默认情况下,Knockout允许click事件继续在更高一层的事件句柄上冒泡执行。
如果需要,你可以通过额外的绑定clickBubble来禁止冒泡。

<div data-bind="click: myDivHandler">
<button data-bind="click: myButtonHandler, clickBubble: false">
Click me
</button>
</div>

(7)传递更多的参数
如果我们想要传递很多参数给调用的方法的话,我们可以在标签中包括对应方法要传递的参数等,如下:

<button data-bind="click: function(data, event) { myFunction('param1', 'param2', data, event) }">
Click me
</button>

但是,如果我们不想要在标签中出现这么多的内容的话,我们可以使用KO的bind方法来进行方法的传递,如下

<button data-bind="click: myFunction.bind($data, 'param1', 'param2')">
Click me
</button>

(8)防止事件的冲突
在默认情况下,Knockoutjs允许事件绑定从一个元素传递到更高一级的元素。
一个DOM元素和他的父元素都使用了click事件,如果我们点击其中一个则两个事件都会执行,此时,我们就可以使用“clickBubble”来制定哪个事件不执行,如下:
<div data-bind="click: myDivHandler">
<button data-bind="click: myButtonHandler, clickBubble: false">
Click me
</button>
</div>

22、event绑定
event绑定在DOM元素上添加指定的事件句柄以便元素被触发的时候执行定义的JavaScript 函数。大部分情况下是用在keypress,mouseover和mouseout上。

var viewModel = {
detailsEnabled: ko.observable(false),
enableDetails: function() {
this.detailsEnabled(true);
},
disableDetails: function() {
this.detailsEnabled(false);
}
};
ko.applyBindings(viewModel);

<div>
<div data-bind="event: { mouseover: enableDetails, mouseout: disableDetails }">
Mouse over me
</div>
<div data-bind="visible: detailsEnabled">
Details
</div>
</div>

23、submit绑定
submit绑定在form表单上添加指定的事件句柄以便该form被提交的时候执行定义的JavaScript 函数。只能用在表单form元素上。
当你使用submit绑定的时候, Knockout会阻止form表单默认的submit动作。换句话说,浏览器会执行你定义的绑定函数而不会提交这个form表单到服务器上。可以很好地解释这个,
使用submit绑定就是为了处理view model的自定义函数的,而不是再使用普通的HTML form表单。如果你要继续执行默认的HTML form表单操作,你可以在你的submit句柄里返回true。

<form data-bind="submit: doSomething">
<button type="submit">
Submit
</button>
</form>

为什么不在submit按钮上使用click绑定?
==>在form上,你可以使用click绑定代替submit绑定。不过submit可以handle其它的submit行为,比如在输入框里输入回车的时候可以提交表单。

24、vlue绑定
(1)value绑定是关联DOM元素的值到view model的属性上。主要是用在表单控件<input>,<select>和<textarea>上。
不管什么时候,只要你更新了元素的值,那 KO都会将view model对应的属性值自动更新。默认情况下当用户离开焦点(例如onchange事件)的时候,
KO才更新这个值,但是你可以通过第2个参数valueUpdate来特别指定改变值的时机。

(2)valueUpdate
如果你使用valueUpdate参数,那就是意味着KO将使用自定义的事件而不是默认的离开焦点事件。下面是一些最常用的选项:
1/“change”(默认值) - 当失去焦点的时候更新view model的值,或者是<select> 元素被选择的时候。
2/“keyup” – 当用户敲完一个字符以后立即更新view model。
3/“keypress” – 当用户正在敲一个字符但没有释放键盘的时候就立即更新view model。不像 keyup,这个更新和keydown是一样的。
4/“afterkeydown” – 当用户开始输入字符的时候就更新view model。主要是捕获浏览器的keydown事件或异步handle事件。

var viewModel = {
someValue: ko.observable("edit me")
};

<p>
Your value:
<input data-bind="value: someValue, valueUpdate: 'afterkeydown'" />
</p>
<p>
You have typed:
<span data-bind="text: someValue">
</span>
</p>

(3)绑定下拉菜单drop-down list(例如SELECT)
(4)更新observable和non-observable属性值

原文地址:https://www.cnblogs.com/qzccl/p/6477684.html