knockout 学习笔记
1、激活knockout
ko.applayBindings()
第一個(gè)參數(shù)是激活ko時(shí)用于聲明綁定的View Model的對(duì)象
(myViewModel= {personName: 'Bob',personAge: 123})
第二個(gè)參數(shù)是可選的,用于設(shè)置要使用data-bind屬性的html元素或容器
(ko.applayBindings(myViewModel, documentElementById("id")))
比如:ko.applyBindings(myViewModel);
2、observables(響應(yīng)一個(gè)對(duì)象)
當(dāng)view model發(fā)生變化時(shí),能夠自動(dòng)更新ui界面
將model屬性聲明成observable
(myViewModel= {personName: ko.observable('Bob'),personAge: ko.observable(123)})
頁(yè)面上如果要和一個(gè)輸入框綁定起來(lái)的話,
(
<input data-bind="value: personName"/>
<span data-bind="text: personName"></span>
)
讀取observable屬性:myViewModel.personName()
設(shè)置observable屬性:myViewModel.personName(""Mary"")
同時(shí)設(shè)置多個(gè)observable屬性:myViewModel.personName(""Mary"").personAge(50) 鏈?zhǔn)秸Z(yǔ)法
3、observableArray(響應(yīng)一個(gè)對(duì)象的集合)
(
var myObservableArray = ko.observableArray(); // 實(shí)例化一個(gè)數(shù)組
myObservableArray.push('Some value'); // 向數(shù)組中添加記錄
myObservableArray.push('Some value');
)
==》Knockoutjs數(shù)組常用的方法如下
(1)myObservableArray.push('Some new value'):增加一個(gè)新的元素
(2)myObservableArray.pop():刪除一個(gè)元素,并返回其值
(3)myObservableArray.unshift('Some new value'):在數(shù)組的開(kāi)始處增加一個(gè)新的元素
(4)myObservableArray.shift():刪除數(shù)組的第一個(gè)元素,并返回其值
(5)myObservableArray.reverse():反轉(zhuǎn)數(shù)組的順序
(6)myObservableArray.sort():數(shù)組排序。排序規(guī)則可以由用戶(hù)自己定義也可以使用默認(rèn),
默認(rèn)情況下按照字母順序或者數(shù)字的順序進(jìn)行排序。自己定義排序規(guī)則時(shí)需要接收數(shù)組 中的兩個(gè)元素,
并且需要返回一個(gè)數(shù)值,當(dāng)此值小于0時(shí)表示第一個(gè)元素較小,當(dāng)此值大于0時(shí),表示第二個(gè)元素較小,
當(dāng)?shù)扔?時(shí)表示兩個(gè)元
myObservableArray.sort(function(left, right) {
return left.lastName == right.lastName ? 0 : (left.lastName < right.lastName ? -1 : 1)
})
(7)myObservableArray.splice():數(shù)組截取。例如:myObservableArray.splice(1, 3),代表從數(shù)組的第一個(gè)元素開(kāi)始,截取三個(gè)元素,并且將他們作為數(shù)組返回。
(8)myObservableArray().length():數(shù)組的長(zhǎng)度
(9)myObservableArray()[0]:取得數(shù)組的第一個(gè)值
(10)myObservableArray.remove(someItem)移除myObservableArray數(shù)組內(nèi)所有匹配someItem的對(duì)象, 并把這些對(duì)象組成一個(gè)數(shù)組返回
(11)myObservableArray.remove(function(item) { return item.age < 18 })移除myObservableArray數(shù)組內(nèi)所有年齡屬性小于18的對(duì)象,并返回這些對(duì)象組成的新數(shù)組
(12)myObservableArray.removeAll(['Chad', 132, undefined])移除myObservableArray數(shù)組內(nèi)所有匹配'Chad',123, orundefined 的對(duì)象并把它們組成新數(shù)組返回
(13)myObservableArray.removeAll()移除myObservableArray數(shù)組內(nèi)所有數(shù)據(jù),并返回這些數(shù)據(jù)組成的一個(gè)新數(shù)組
然則基于下述來(lái)由,凡是推薦應(yīng)用KO中的等價(jià)辦法:
(14)KO中的辦法支撐所有主流瀏覽器(比如,Javascript原生辦法indexOf在<=IE8時(shí)不正常,而KO的indexOf 能正常工作)
(15)dependency tracking
(16)語(yǔ)法加倍簡(jiǎn)潔:調(diào)用KO中的辦法應(yīng)用myObservableArray.push(...),調(diào)用原生Javascript中的辦法應(yīng)用myObservableArray().push(...)
4、computed(計(jì)算屬性,依賴(lài)一個(gè)或者多個(gè)屬性)
(
法一:
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、依賴(lài)鏈工作
(1)用items監(jiān)控屬性來(lái)代表一組items項(xiàng)
(2)另外一個(gè)selectedIndexes監(jiān)控屬性來(lái)用戶(hù)已選擇項(xiàng)目的索引
(3)一個(gè)selectedItems依賴(lài)屬性來(lái)返回一組用戶(hù)已選擇的Item對(duì)象
(4)另外一個(gè)依賴(lài)屬性來(lái)返回true或者false,來(lái)表示selectedItems中是否包含一些屬性(如新的或尚未保存的)。一些UI元素,比如一個(gè)按鈕可以基于此值來(lái)控制其啟用或禁止。
然后,當(dāng)改變items或者selectedIndexes都會(huì)影響到所有的依賴(lài)屬性鏈,然后依次更新到綁定了這些項(xiàng)的UI。非常的整潔和優(yōu)雅。
6、可寫(xiě)的計(jì)算屬性==》提供一個(gè)回調(diào)函數(shù)來(lái)實(shí)現(xiàn)值的寫(xiě)入
(1)分解用戶(hù)輸入
比如:// 這里全名是可以寫(xiě)入的,但是firstName和lastName是不可寫(xiě)入的
(
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)值轉(zhuǎn)換
(
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)篩選和驗(yàn)證用戶(hù)輸入 ==》監(jiān)控屬性isValid來(lái)表示最后一次寫(xiě)入是否合法,然后根據(jù)真假值顯示相應(yīng)的提示信息
(
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、確定一個(gè)屬性是不是依賴(lài)屬性
ko.isComputed()
8、依賴(lài)屬性參考
一個(gè)依賴(lài)屬性可以通過(guò)以下方式實(shí)現(xiàn):
(1)ko.computed( evaluator [, targetObject, options] )這是用于創(chuàng)建依賴(lài)屬性的一種最常見(jiàn)的方式。
evaluator--用于計(jì)算一個(gè)依賴(lài)屬性當(dāng)值的方法
targetObject--如果給定,當(dāng)KO調(diào)用回調(diào)函數(shù)時(shí),定義一個(gè)值表示
this--參閱管理”this”來(lái)了解更多信息。
options--依賴(lài)屬性的參數(shù)對(duì)象。可以參看下面詳細(xì)的清單。
(2)ko.computed( options )--單一參數(shù)方式接受一個(gè)JavaScript對(duì)象或者以下任意屬性來(lái)創(chuàng)建一個(gè)依賴(lài)屬性
read--必需參數(shù),傳入方法。用于運(yùn)算當(dāng)前依賴(lài)屬性當(dāng)前值的方法。
write–可選參數(shù),傳入方法。如果給定,將會(huì)使依賴(lài)屬性可寫(xiě)這個(gè)方法接收一個(gè)外部的值來(lái)寫(xiě)入到依賴(lài)屬性中。它通常是使用你自己定義的邏輯來(lái)處理傳入的值,通常將值寫(xiě)入到相關(guān)的監(jiān)控屬性中。
owner–可選參數(shù),傳入對(duì)象。
傳入的對(duì)象作為this的關(guān)鍵字在KO調(diào)用read和write方法使用。
deferEvaluation–可選參數(shù),傳入ture或者false。如果設(shè)置為true,則依賴(lài)屬性的值直到有實(shí)際訪問(wèn)它之前它的值是不會(huì)重新計(jì)算的。默認(rèn)情況下,依賴(lài)屬性的值在創(chuàng)建過(guò)程中就已經(jīng)初始化了。
disposeWhen–可選參數(shù),傳入方法。如果給出,該傳入方法將會(huì)在每一次運(yùn)算結(jié)束之后被調(diào)用來(lái)釋放依賴(lài)屬性。真正的結(jié)果就是觸發(fā)依賴(lài)屬性的disposal方法。
disposeWhenNodeIsRemoved–可選參數(shù),傳入方法。如果給出,當(dāng)指定的DOM元素被KO刪除的時(shí)候依賴(lài)屬性的disposal方法會(huì)被觸發(fā)。當(dāng)元素的綁定被模版或者控制流程綁定方法移除的時(shí)候,此功能是用來(lái)釋放依賴(lài)屬性。
依賴(lài)屬性提供了以下方法:
dispose()–釋放依賴(lài)屬性,清除所有的依賴(lài)訂閱。此方法非常有用,當(dāng)你想停止一個(gè)依賴(lài)屬性以避免其更新或者清除一個(gè)內(nèi)存中的依賴(lài)屬性而那些存在依賴(lài)關(guān)系的監(jiān)控值是不會(huì)被清除的。
extend(extenders)–用于擴(kuò)展依賴(lài)屬性。
getDependenciesCount()–返回依賴(lài)屬性當(dāng)前依賴(lài)關(guān)系數(shù)量。
getSubscriptionsCount()–返回依賴(lài)屬性當(dāng)前訂閱數(shù)量(無(wú)論是其他的依賴(lài)屬性或手動(dòng)訂閱)。
isActive ()–返回依賴(lài)屬性在以后是否會(huì)被更新,一個(gè)依賴(lài)屬性如果沒(méi)有依賴(lài)關(guān)系是無(wú)效的。
peek ()–返回當(dāng)前依賴(lài)屬性的值而無(wú)需創(chuàng)建依賴(lài)關(guān)系(可以參考peek)。
subscribe( callback [,callbackTarget, event] )–注冊(cè)一個(gè)手動(dòng)訂閱來(lái)通知依賴(lài)屬性的變化。
9、數(shù)據(jù)綁定
數(shù)據(jù)綁定有三種方式:
One-Time(一次綁定)
One-Way(單向綁定)當(dāng)viewModel發(fā)生變化時(shí),ui也會(huì)隨之變化
Two-way(雙向綁定)這是最靈活的數(shù)據(jù)綁定,也是代價(jià)最大的
11、注冊(cè)自己的訂閱來(lái)通知監(jiān)控屬性的變化
(
var subscription = myViewModel.personName.subscribe(function(newValue) {
console.info("The person's new name is " + newValue);
});
)
12、終止自己的訂閱:首先獲取到這個(gè)訂閱,然后調(diào)用dispose 方法即可。
(
subscription.dispose();
)
13、visable==>用來(lái)控制DOM元素的顯示和隱藏
如果參數(shù)是一個(gè)observable值,visible綁定使得元素的visible狀態(tài)隨著參數(shù)值的變化而變化。
如果參數(shù)不是observable值,visible綁定僅僅會(huì)設(shè)置元素visible狀態(tài)一次,以后不會(huì)再更新。
(
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>
)
也可以使用函數(shù)或者表達(dá)式來(lái)控制元素的顯示和隱藏
(
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>這樣的元素上非常有用,而實(shí)際上你可以綁定任何元素。
(1) 是用函數(shù)或者表達(dá)式來(lái)決定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>
但是如果不需要?jiǎng)?chuàng)建計(jì)算屬性的話,可以直接使用:
<span data-bind="text: price() >50 ? 'expensive' : 'affordable'"></span>
)
(2) 關(guān)于html編碼
如果直接使用:viewModel.myMessage("<i>Hello, world!</i>");不會(huì)顯示一個(gè)斜體文本,會(huì)按遠(yuǎn)洋標(biāo)簽進(jìn)行輸出
(3)使用“text”而沒(méi)有一個(gè)容器元素
有時(shí)你可能需要使用Knockout在不使用多余的元素的情況下通過(guò)text綁定來(lái)設(shè)置文本內(nèi)容。例如,在option元素中是不允許存在其他元素的,所以下面的綁定是無(wú)法正常工作的。
<select data-bind="foreach: items">
<option>Item<span data-bind="text: name"></span></option>
</select>
為了解決這個(gè)問(wèn)題,你可以使用容器語(yǔ)法,它基于一個(gè)注釋元素。
<select data-bind="foreach: items">
<option>Item<!--ko text: name--><!--/ko--></option>
</select>
<!--ko-->和<!--/ko-->注釋標(biāo)記作為起始和結(jié)束符,定義一個(gè)“虛擬元素”,里面包含了標(biāo)記,Knockout能夠識(shí)別這種虛擬元素語(yǔ)法和綁定作為你需要的容器元素而存在。
15、html綁定
KO設(shè)置該參數(shù)值到元素的innerHTML屬性上,元素之前的內(nèi)容將被覆蓋。
如果參數(shù)是監(jiān)控屬性observable的,那元素的內(nèi)容將根據(jù)參數(shù)值的變化而更新,如果不是,那元素的內(nèi)容將只設(shè)置一次并且以后不在更新。
如果你傳的是不是數(shù)字或者字符串(例如一個(gè)對(duì)象或者數(shù)組),那顯示的文本將是yourParameter.toString()的等價(jià)內(nèi)容。
ps: 因?yàn)樵摻壎ㄔO(shè)置元素的innerHTML,你應(yīng)該注意不要使用不安全的HTML代碼,因?yàn)橛锌赡芤鹉_本注入攻擊。如果你不確信是否安全(比如顯示用戶(hù)輸入的內(nèi)容),
那你應(yīng)該使用text綁定,因?yàn)檫@個(gè)綁定只是設(shè)置元素的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類(lèi)名綁定
ps: 如果你想使用my-class class,你不能寫(xiě)成這樣:
<div data-bind="css: { my-class: someValue }">...</div>
要這樣寫(xiě):
<div data-bind="css: { 'my-class': someValue }">...</div>
(
var viewModel = {
currentProfit: ko.observable(150000) // 如果大于0則刪除這個(gè)CSS class
};
當(dāng)currentProfit 小于0的時(shí)候,添加profitWarning CSS class到元素上,
viewModel.currentProfit(-50);
)
17、style屬性綁定
注:應(yīng)用的style的名字不是合法的JavaScript變量命名
如果你需要應(yīng)用font-weight或者text-decoration,你不能直接使用,而是要使用style對(duì)應(yīng)的JavaScript名稱(chēng)。
錯(cuò)誤:{ font-weight: someValue }; 正確:{ fontWeight: someValue }
錯(cuò)誤:{ 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屬性綁定
注:應(yīng)用的屬性名字不是合法的JavaScript變量命名,比如屬性名稱(chēng)是data-something的話,要記得加引號(hào)
(
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)循環(huán)遍歷輸出某個(gè)數(shù)組、集合中的內(nèi)容
(
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)動(dòng)態(tài)增加和刪除遍歷節(jié)點(diǎn)
其中: $index: 獲得當(dāng)前項(xiàng)的位置,從0開(kāi)始
$parent: 指代this,當(dāng)前 綁定的模型數(shù)據(jù) 的 父模型數(shù)據(jù).
$parentContext 指 當(dāng)前 綁定的模型數(shù)據(jù) 的父模型數(shù)據(jù)的上下文.
(
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: 輸出數(shù)組中的所有元素
(
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來(lái)為我們要遍歷的元素起一個(gè)別名
(
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)在沒(méi)有綁定屬性的情況下使用foreach
我們就沒(méi)有一個(gè)可以綁定foreach的元素,此時(shí)我們可以通過(guò)以下的代碼來(lái)實(shí)現(xiàn):
ps: 使用<!--ko--><!--/ko-->來(lái)表示循環(huán)的開(kāi)始和結(jié)束,這是一個(gè)虛擬的標(biāo)簽,
Knockoutjs能夠?qū)ζ渲械膄oreach進(jìn)行綁定就好像你將foreach綁定到了一個(gè)真實(shí)的標(biāo)簽上一樣。
(
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)默認(rèn)不顯示被標(biāo)示為刪除的元素
有的時(shí)候我們要跳過(guò)數(shù)組中的一些元素,此時(shí)這些元素已經(jīng)被標(biāo)示為刪除,
但并沒(méi)有被真實(shí)刪除,這些元素當(dāng)我們使用foreach輸出的時(shí)候是默認(rèn)不顯示的,
如果我們想要這些元素顯示的話,我們可以使用includeDestroyed這個(gè)選項(xiàng),比如:
(
<div data-bind='foreach: { data: myArray, includeDestroyed: true }'>
</div>
)
19、if binding 和 if not binding ==》 data-bind="if" / data-bind= "checked"
ps: 使用if是真正的控制html是否出現(xiàn)在DOM中,會(huì)修改dom結(jié)構(gòu),出于性能的考慮,不應(yīng)該頻繁修改if的綁定值
使用if binding可以控制某個(gè)組件動(dòng)態(tài)顯示,類(lèi)似我們之前接觸到的visible屬性,不過(guò)此屬性綁定過(guò)以后就不能更改,
而if binding可以根據(jù)相應(yīng)的條件控制組件是否顯示
(
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來(lái)判斷某個(gè)元素是否為null,如果為null則不會(huì)顯示
(
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來(lái)重新定義一個(gè)上下文綁定
(
使用coords下的latitude和longitude的時(shí)候我們就不需要使用
coords.latitude來(lái)調(diào)用了,因?yàn)槲覀兪褂脀ith:coords來(lái)指定了coords的上下文,當(dāng)我們使用coords下面的屬性時(shí)就可以直接使用了
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>
)
==》動(dòng)態(tài)交互的例子==》沒(méi)懂
(
<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)傳參數(shù)給你的click 句柄 ==》傳一個(gè)function包裝的匿名函數(shù)
(
var viewModel = {
myClickFunction: function(opts) {
console.info(opts)
}
};
ko.applyBindings(viewModel);
<button data-bind="click: function() { viewModel.myClickFunction('ccl')}">
Click me 帶參
</button>
)
(3)訪問(wèn)事件源對(duì)象
(
var viewModel = {
myFunction: function(event) {
if (event.shiftKey) {
//do something different when user has shift key down
} else {
//do normal action
}
}
};
)
如果需要的話,可以使用匿名函數(shù)的第一個(gè)參數(shù)傳進(jìn)去,然后在里面調(diào)用:
(
<button data-bind="click: function(event) { viewModel.myFunction(event, 'param1') }">
Click me
</button>
)
(4)允許執(zhí)行默認(rèn)事件
默認(rèn)情況下,Knockout會(huì)阻止冒泡,防止默認(rèn)的事件繼續(xù)執(zhí)行。例如,如果你點(diǎn)擊一個(gè)a連接,在執(zhí)行完自定義事件時(shí)它不會(huì)連接到href地址。這特別有用是因?yàn)槟愕淖远x事件主要就是操作你的view model,而不是連接到另外一個(gè)頁(yè)面。
當(dāng)然,如果你想讓默認(rèn)的事件繼續(xù)執(zhí)行,你可以在你click的自定義函數(shù)里返回true。
(5)控制this句柄
KO在調(diào)用你定義的函數(shù)時(shí),會(huì)將view model傳給this對(duì)象(也就是ko.applyBindings使用的view model)。主要是方便你在調(diào)用你在view model里定義的方法的時(shí)候可以很容易再調(diào)用view model里定義的其它屬性。
如果你想引用其它對(duì)象,我們有兩種方式:
你可以和(2)里那樣使用匿名函數(shù),因?yàn)樗С秩我釰avaScript 對(duì)象。
你也可以直接引用任何函數(shù)對(duì)象。你可以使用bind使callback函數(shù)設(shè)置this為任何你選擇的對(duì)象。例如:
(
<button data-bind="click: someObject.someFunction.bind(someObject)">
Click me
</button>
)
(6)防止事件冒泡clickBubble: false
默認(rèn)情況下,Knockout允許click事件繼續(xù)在更高一層的事件句柄上冒泡執(zhí)行。
如果需要,你可以通過(guò)額外的綁定clickBubble來(lái)禁止冒泡。
(
<div data-bind="click: myDivHandler">
<button data-bind="click: myButtonHandler, clickBubble: false">
Click me
</button>
</div>
)
(7)傳遞更多的參數(shù)
如果我們想要傳遞很多參數(shù)給調(diào)用的方法的話,我們可以在標(biāo)簽中包括對(duì)應(yīng)方法要傳遞的參數(shù)等,如下:
(
<button data-bind="click: function(data, event) { myFunction('param1', 'param2', data, event) }">
Click me
</button>
)
但是,如果我們不想要在標(biāo)簽中出現(xiàn)這么多的內(nèi)容的話,我們可以使用KO的bind方法來(lái)進(jìn)行方法的傳遞,如下
(
<button data-bind="click: myFunction.bind($data, 'param1', 'param2')">
Click me
</button>
)
(8)防止事件的沖突
在默認(rèn)情況下,Knockoutjs允許事件綁定從一個(gè)元素傳遞到更高一級(jí)的元素。
一個(gè)DOM元素和他的父元素都使用了click事件,如果我們點(diǎn)擊其中一個(gè)則兩個(gè)事件都會(huì)執(zhí)行,此時(shí),我們就可以使用“clickBubble”來(lái)制定哪個(gè)事件不執(zhí)行,如下:
<div data-bind="click: myDivHandler">
<button data-bind="click: myButtonHandler, clickBubble: false">
Click me
</button>
</div>
22、event綁定
event綁定在DOM元素上添加指定的事件句柄以便元素被觸發(fā)的時(shí)候執(zhí)行定義的JavaScript 函數(shù)。大部分情況下是用在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被提交的時(shí)候執(zhí)行定義的JavaScript 函數(shù)。只能用在表單form元素上。
當(dāng)你使用submit綁定的時(shí)候, Knockout會(huì)阻止form表單默認(rèn)的submit動(dòng)作。換句話說(shuō),瀏覽器會(huì)執(zhí)行你定義的綁定函數(shù)而不會(huì)提交這個(gè)form表單到服務(wù)器上??梢院芎玫亟忉屵@個(gè),
使用submit綁定就是為了處理view model的自定義函數(shù)的,而不是再使用普通的HTML form表單。如果你要繼續(xù)執(zhí)行默認(rèn)的HTML form表單操作,你可以在你的submit句柄里返回true。
(
<form data-bind="submit: doSomething">
<button type="submit">
Submit
</button>
</form>
)
為什么不在submit按鈕上使用click綁定?
==>在form上,你可以使用click綁定代替submit綁定。不過(guò)submit可以handle其它的submit行為,比如在輸入框里輸入回車(chē)的時(shí)候可以提交表單。
24、vlue綁定
(1)value綁定是關(guān)聯(lián)DOM元素的值到view model的屬性上。主要是用在表單控件<input>,<select>和<textarea>上。
不管什么時(shí)候,只要你更新了元素的值,那 KO都會(huì)將view model對(duì)應(yīng)的屬性值自動(dòng)更新。默認(rèn)情況下當(dāng)用戶(hù)離開(kāi)焦點(diǎn)(例如onchange事件)的時(shí)候,
KO才更新這個(gè)值,但是你可以通過(guò)第2個(gè)參數(shù)valueUpdate來(lái)特別指定改變值的時(shí)機(jī)。
(2)valueUpdate
如果你使用valueUpdate參數(shù),那就是意味著KO將使用自定義的事件而不是默認(rèn)的離開(kāi)焦點(diǎn)事件。下面是一些最常用的選項(xiàng):
1/“change”(默認(rèn)值) - 當(dāng)失去焦點(diǎn)的時(shí)候更新view model的值,或者是<select> 元素被選擇的時(shí)候。
2/“keyup” – 當(dāng)用戶(hù)敲完一個(gè)字符以后立即更新view model。
3/“keypress” – 當(dāng)用戶(hù)正在敲一個(gè)字符但沒(méi)有釋放鍵盤(pán)的時(shí)候就立即更新view model。不像 keyup,這個(gè)更新和keydown是一樣的。
4/“afterkeydown” – 當(dāng)用戶(hù)開(kāi)始輸入字符的時(shí)候就更新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屬性值
?
轉(zhuǎn)載于:https://www.cnblogs.com/qzccl/p/6477684.html
總結(jié)
以上是生活随笔為你收集整理的knockout 学习笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 为什么MonstersDomainDem
- 下一篇: 位图上日文怎么翻译呀,哪位大神帮个忙