(更新)knockout.js學習——1.7例子——繫結的詳細語法
阿新 • • 發佈:2019-01-23
建立自定義模板
1、註冊繫結
新增子屬性到ko.bindingHandlers.yourBindingName ={};註冊繫結。
init和update可以只定義其中一個。
(1)初始化:init
// 建立初始化狀態,事件處理等等
(2)更新:update
// 無論何時相關聯的observable改變value時候
// 基於應用values的DOM元素
(3)在DOM元素上使用: <div data-bind="yourBindingName:
someValue"></div>
2、詳細解釋
ko.bindingHandlers.yourBindingName ={
init:function
(element,valueAccessor,allBindingsAccessor,viewModel){},
update:function
(element,valueAccessor,allBindingsAccessor,viewModel)
}
引數:
element——使用這個繫結的DOM元素。
valueAccessor——Javascript函式。通過valueAccessor()可以得到應用到這個繫結的model上的當前屬性值。
另一種翻譯:得到是當前進入繫結的內容。是observable不是值。可以是表示式的值。
allBindingsAccessor--Javascript函式。通過allBindingsAccessor()得到這個元素上所有model的屬性值。
另一種翻譯:得到其他繫結,並列入繫結屬性中。一般用來訪問其他繫結。這使您可以訪問所有的其他繫結在同一列資料繫結屬性。這通常是用於訪問其他與此結合相互作用的繫結。這些繫結可能不會有任何相關的程式碼,只是一種方法,通過附加選項的約束力,除非你選擇的多個屬性為您的主要結合傳遞一個物件。例如,optionsvalue,optionstext,和optionscaption是繫結,只能通過選項選項結合。
(1) init回撥:
knockout在dom元素使用自定義繫結的時候會呼叫你的init函式。 init有兩個重要的用途:為dom元素設定初始值;註冊事件控制代碼,例如當用戶點選或者編輯DOM元素的時候,可以改變相關的observable值的狀態。ko會傳遞和update回撥函式一樣的引數。
你可以像讓slideVisible在頁面第一次顯示的時候設定該元素的狀態(但是不使用任何動畫效果),而只是讓動畫在以後改變的時候再執行。
你可以這樣來做:
ko.bindingHandlers.slideVisible = {
init: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor
());
// Get the current value of the current property we're
bound to
$(element).toggle(value);
// jQuery will hide/show the element depending on
whether "value" or true or false
},
update: function(element, valueAccessor,
allBindingsAccessor) {
// Leave as before
}
};
這就是說giftWrap的初始值宣告的是false(例如giftWrap: ko.observable(false)),然後讓初始值會讓關聯的DIV隱藏,之後使用者點選checkbox的時候會讓元素顯示出來。
(2)update回撥
通過visible繫結來控制一個元素的可見性,但是想讓該元素在隱藏或者顯示的時候加入動畫效果。可以自定義自己的繫結來呼叫jquery的slideUp/slideDown函式。
ko.bindingHandlers.slideVisible = {
update: function
(element,valueAccessor,allBindingsAccessor){
// get the latest data that bound to
var value = valueAccessor(), allBindings =
allBindingsAccessor();
// next,whether or not the supplied model property is
observable,get its current value.
var valueUnwrapped = ko.utils.unwrapObservable(value);
// grab some more data from another bingding property
var duration = allBindings.slideDuration || 500;
// 500 is default duration unless otherwise specified
// now manipulate the dom element
if(valueUnwrapped == true) $(element).slideDown(duration);
else $(element).slideUp(duration);
}
};
1、陣列繫結
this.items = ko.observableArray([
{ id: 1, name: "Apple Pie" },
{ id: 2, name: "Pumpkin Pie" },
{ id: 3, name: "Blueberry Torte" }
]);
this.items.push({ id: 4, "Strawberry Shortcake" });
重要是要注意,ObservableArrays跟蹤數組裡的item更改,而不是單獨的一個item的屬性。在上面的例子中,如果你的應用需要跟蹤item的name,那麼name屬性需要也加一個observable。
2、在IE6下,如果有空格要寫 否則不呈現空格。
一、控制文字和展現
1、text繫結
2、visible繫結
3、html繫結
<div data-bind="html: details"></div>
<script type="text/javascript">
var viewModel = {
details: ko.observable() // Initially blank
};
viewModel.details("<em>For further details, view the
report <a href='report.html'>here</a>.</em>"); // HTML content
appears
</script>
4、如果你提供的不是數字或者字串,你傳遞的是物件或陣列等,innerHTML/text bingding和yourParameter.toString()效果一樣。
5、css繫結
<div data-bind="css: { profitWarning: currentProfit() < 0 }">
Profit Information
</div>
<script type="text/javascript">
var viewModel = {
currentProfit: ko.observable(150000) // Positive
value, so initially we don't apply the "profitWarning" class
};
viewModel.currentProfit(-50); // Causes the
"profitWarning" class to be applied
</script>
當currentProfit()<0時,css樣式名"profitWarning"就增加,否則移除這個css。
動態切換兩個css:
<div data-bind="css: profitStatus">
Profit Information
</div>
<script type="text/javascript">
var viewModel = {
currentProfit: ko.observable(150000)
};
// Evalutes to a positive value, so initially we apply the
"profitPositive" class
viewModel.profitStatus = ko.computed(function() { //
computed
return this.currentProfit() < 0 ? "profitWarning" :
"profitPositive";
}, viewModel);
// Causes the "profitPositive" class to be removed and
"profitWarning" class to be added
viewModel.currentProfit(-50);
</script>
可以同時使用多個css繫結:
<div data-bind="css: { profitWarning: currentProfit() < 0, majorHighlight: isSevere }">
當類標誌不合法時,如profitWarning,給其加上引號:'profitWarning'
6、style 繫結
<div data-bind="style: { color: currentProfit() < 0 ? 'red' :
'black', fontWeight: isSevere() ? 'bold' : '' }">...</div>
7、attr繫結
<a data-bind="attr: { href: url, title: details }">
Report
</a>
<script type="text/javascript">
var viewModel = {
url: ko.observable("year-end.html"),
details: ko.observable("Report including final year-
end statistics")
};
</script>
attr屬性名字不合法時,加上引號就可以。
二、控制流繫結
1、foreach繫結
foreach繫結複製進入一個數組的標記部分,繫結每一個複製標記到相應的陣列條目。可以和其他控制流的if、with一起使用。
<h4>People</h4>
<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>
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());
$index:序號
$parent:上一級元素
(1)$data
foreach塊可以在陣列項引用屬性,但是如果希望在陣列條目本身時引入屬性:
用$data代表每一項。
顯示每一項的具體內容:
<td data-bind="text: $data.firstName"></td>
(2)別名:as,加上引號,是給一個新名字為新的變數,不是改變值。
任何foreach迴圈內部,都會引用別名進入現在的陣列條目。這在祖先元素已經巢狀foreach塊,而且你需要在更高一層引用一個條目宣告時很有用。
<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>
<script>
var viewModel = {
categories: ko.observableArray([
{ name: 'Fruit', items: [ 'Apple', 'Orange',
'Banana' ] },
{ name: 'Vegetables', items: [ 'Celery', 'Corn',
'Spinach' ] }
])
};
ko.applyBindings(viewModel);
</script>
(3)只有部分元素迴圈遍歷,加上包裹元素在內部(如例子中的span標籤)。使用<!---->
<ul>
<li class="header">Header item</li>
<!-- ko foreach: myItems -->
<li>Item <span data-bind="text: $data"></span></li>
<!-- /ko -->
</ul>
<script type="text/javascript">
ko.applyBindings({
myItems: [ 'A', 'B', 'C' ]
});
</script>
(4)想要顯示銷燬的條目,使用includeDestroyed
<div data-bind='foreach: { data: myArray, includeDestroyed:
true }'>
...
</div>
(5)執行動畫效果
afterRender/afterAdd/beforeRemove/beforeMove/afterMove
<ul data-bind="foreach: { data: myItems, afterAdd:
yellowFadeIn }">
<li data-bind="text: $data"></li>
</ul>
<button data-bind="click: addItem">Add</button>
<script type="text/javascript">
ko.applyBindings({
myItems: ko.observableArray([ 'A', 'B', 'C' ]),
yellowFadeIn: function(element, index, data) {
$(element).filter("li")
.animate({ backgroundColor: 'yellow' },
200)
.animate({ backgroundColor: 'white' },
800);
},
addItem: function() { this.myItems.push('New item'); }
});
</script>
afterRender: 在foreach塊複製到文件中或foreach初始化,或新的條
目增加到陣列中,konckout將會提供如下引數到回撥函式中:
插入到陣列中的dom元素
對應被繫結的資料條目
afterAdd:當新條目增加到陣列中時激發。一般用來回調一個方法,比如$().fadeIn(),得到動畫過度當條目增加時。knockout會提供如下引數:
被增加的dom節點,增加的陣列元素index,增加的陣列元素
beforeMove:當陣列條目在陣列中的位置發生改變,且在對應dom節點被移除前 被激發。它適用於所有序號改變的陣列元素,所以當你插入一個數組條目在陣列中,回撥函式會激發其他元素,知道他們的序號位置已經增加了1。可以使用beforeMove來儲存收影響元素的原始螢幕座標。這樣你可以使他們在afterMove回撥函式中動畫過度。
提供的回撥引數:
將要移動的dom節點,移動的陣列元素的序號,移動的陣列元素。
afterMove:當陣列中的陣列條目已經改變位置時,在foreach已經更新dom來匹配之後,被激發。
afterMove適用於所有序號被改變的陣列元素,回撥函式會激發其他元素,直到他們的序號位置都已經增加一。
konockout提供的回撥引數:
將要被移除的dom節點,移動的陣列元素的序號,移動的陣列元素。
2、if繫結
if和visible
if和visible差不多。不同在於,使用visible,包括標籤保持在dom中,經常使用data-bind屬性——visible繫結使用css來切換標籤的可見性。if只在表示式為真的情況下適用於增加或移除dom中繫結的後代元素包括的標籤。
例子:
<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>
<script>
ko.applyBindings({
planets: [
{ name: 'Mercury', capital: null },
{ name: 'Earth', capital: { cityName: 'Barnsley' }
}
]
});
</script>
在以上例子中,因為if,capital為null就不用繼續執行,發生錯誤:
計算後續capital.cityName不存在的屬性了。在javascript中,可以判斷if:capital判斷是否為空,但是不允許計算為空的值:
capital.cityName。
if後面的語句為true,顯示包含的標籤。
if後面的語句為false,包含的標籤將會從document中移走而不是適用於任何剛開始的繫結。
如果表示式提及到任何可觀測值,當它們改變時表示式會被重新計算。
相應的,帶有if標籤塊將會動態增加和移除當表示式結果發生改變時。
data-bind屬性將會被用於一個新的副本包含標籤。
當想要實現控制某一部分標籤顯示隱藏,
使用<!-- ko --><!-- /ko -->
<ul>
<li>This item always appears</li>
<!-- ko if: someExpressionGoesHere -->
<li>I want to make this item present/absent
dynamically</li>
<!-- /ko -->
</ul>
3、ifnot繫結
和if一樣。完全可以用if代替。
4、with繫結
with繫結建立了一個新的上下文,所以後代元素被繫結一個詳細的物件上下文。
可以任意使用其他控制流繫結如if/foreach和巢狀with繫結。
以下是一個簡單的切換繫結上下文到子物件。
注意data-bind屬性,沒有必要加上latitude和longitude的字首
coords.。因為繫結上下文已經切換到coords了。
<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>
<script type="text/javascript">
ko.applyBindings({
city: "London",
coords: {
latitude: 51.5001524,
longitude: -0.1262362
}
});
</script>
複雜一點的with例子:
<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>
function AppViewModel() {
var self = this;
self.twitterName = ko.observable('@example');
self.resultData = ko.observable(); // No initial value
self.getTweets = function() {
var name = self.twitterName(),
simulatedResults = [
{ text: name + ' What a nice day.' },
{ text: name + ' Building some cool apps.' },
{ text: name + ' Just saw a famous celebrity
eating lard. Yum.' }
];
self.resultData({ retrievalDate: new Date(),
topTweets: simulatedResults });
}
self.clearResults = function() {
self.resultData(undefined);
}
}
ko.applyBindings(new AppViewModel());
with繫結動態增加移除後代元素依賴於聯絡的值是null/undefined或非空。
如果需要訪問父元素繫結的上下文中的data/functions,可以使用
$parent和root。
關於with的子屬性設定的兩種寫法:
1、寫在viewmodel物件中
var viewModel ={
lcon: {
lname: "lfwefw ",
showCon: [
{ name: "s", textInput: "second" },
{ name: "t", textInput: "third" },
{ name: "f", textInput: "first" }]
}
}
2、用建立viewModel函式的寫法
function AppViewModel() {
var self = this;
self.resultData({ retrievalDate: new Date(), topTweets:
simulatedResults });
}
與其他沒有包括標籤一樣:
<ul>
<li>Header element</li>
<!-- ko with: outboundFlight -->
...
<!-- /ko -->
<!-- ko with: inboundFlight -->
...
<!-- /ko -->
</ul>
<title></title>
<script type="text/javascript" src="js/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="js/jquery.tmpl.js"></script>
<script type="text/javascript" src="js/knockout-3.1.0.js"></script>
<script type="text/javascript" src="js/knockout.simpleGrid.js"></script>
<style type="text/css">
</style>
</head>
<body>
<form data-bind="submit: showDetail">
<div>
Your Account:<input type="text" data-bind="value: inputCon" />
<button type="submit">提交資訊</button>
</div>
</form>
<div data-bind="visible: hiddenDetail">
<div data-bind="text: inputCon"></div>
<div data-bind="with: lcon">
<div data-bind="text: lname"></div>
<div data-bind="foreach: showCon">
hello:<span data-bind="text: name"></span>
<span data-bind=" text: name"></span>
<br />
</div>
</div>
<button type="submit" data-bind="click: clearCon">隱藏</button>
</div>
<script type="text/javascript">
var viewModel = {
inputCon: ko.observable("@mail"),
showDetail: ko.observable(true),
hiddenDetail: ko.observable(false)
,
lcon: {
lname: "lfwefw ",
showCon: [
{ name: "s", textInput: "second" },
{ name: "t", textInput: "third" },
{ name: "f", textInput: "first" }]
}
};
viewModel.showDetail = function () { viewModel.hiddenDetail(true); }
viewModel.clearCon = function () { viewModel.hiddenDetail(false); }
ko.applyBindings(viewModel);
</script>
</body>
1、註冊繫結
新增子屬性到ko.bindingHandlers.yourBindingName ={};註冊繫結。
init和update可以只定義其中一個。
(1)初始化:init
// 建立初始化狀態,事件處理等等
(2)更新:update
// 無論何時相關聯的observable改變value時候
// 基於應用values的DOM元素
(3)在DOM元素上使用: <div data-bind="yourBindingName:
someValue"></div>
2、詳細解釋
ko.bindingHandlers.yourBindingName ={
init:function
(element,valueAccessor,allBindingsAccessor,viewModel){},
update:function
(element,valueAccessor,allBindingsAccessor,viewModel)
}
引數:
element——使用這個繫結的DOM元素。
valueAccessor——Javascript函式。通過valueAccessor()可以得到應用到這個繫結的model上的當前屬性值。
另一種翻譯:得到是當前進入繫結的內容。是observable不是值。可以是表示式的值。
allBindingsAccessor--Javascript函式。通過allBindingsAccessor()得到這個元素上所有model的屬性值。
另一種翻譯:得到其他繫結,並列入繫結屬性中。一般用來訪問其他繫結。這使您可以訪問所有的其他繫結在同一列資料繫結屬性。這通常是用於訪問其他與此結合相互作用的繫結。這些繫結可能不會有任何相關的程式碼,只是一種方法,通過附加選項的約束力,除非你選擇的多個屬性為您的主要結合傳遞一個物件。例如,optionsvalue,optionstext,和optionscaption是繫結,只能通過選項選項結合。
viewModel--傳遞給ko.applyBindings使用的view model引數,如果是模板內部的話,這個引數就是傳遞給模板的資料。
另一種翻譯:通常以data代替避免混淆呼叫此引數資料。外模板繫結,這將提供對你的整體檢視模型。在一個模板,這將被繫結到模板資料。例如,使用的模板的結合foreach選項時,檢視模型引數會被設定為當前陣列成員通過模板傳送。大多數時候,valueaccessor會給你你想要的資料,而檢視模型引數是特別有用,如果你需要一個物件是你的目標的時候,你的call/apply功能。
(1) init回撥:
knockout在dom元素使用自定義繫結的時候會呼叫你的init函式。 init有兩個重要的用途:為dom元素設定初始值;註冊事件控制代碼,例如當用戶點選或者編輯DOM元素的時候,可以改變相關的observable值的狀態。ko會傳遞和update回撥函式一樣的引數。
你可以像讓slideVisible在頁面第一次顯示的時候設定該元素的狀態(但是不使用任何動畫效果),而只是讓動畫在以後改變的時候再執行。
你可以這樣來做:
ko.bindingHandlers.slideVisible = {
init: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor
());
// Get the current value of the current property we're
bound to
$(element).toggle(value);
// jQuery will hide/show the element depending on
whether "value" or true or false
},
update: function(element, valueAccessor,
allBindingsAccessor) {
// Leave as before
}
};
這就是說giftWrap的初始值宣告的是false(例如giftWrap: ko.observable(false)),然後讓初始值會讓關聯的DIV隱藏,之後使用者點選checkbox的時候會讓元素顯示出來。
(2)update回撥
通過visible繫結來控制一個元素的可見性,但是想讓該元素在隱藏或者顯示的時候加入動畫效果。可以自定義自己的繫結來呼叫jquery的slideUp/slideDown函式。
ko.bindingHandlers.slideVisible = {
update: function
(element,valueAccessor,allBindingsAccessor){
// get the latest data that bound to
var value = valueAccessor(), allBindings =
allBindingsAccessor();
// next,whether or not the supplied model property is
observable,get its current value.
var valueUnwrapped = ko.utils.unwrapObservable(value);
// grab some more data from another bingding property
var duration = allBindings.slideDuration || 500;
// 500 is default duration unless otherwise specified
// now manipulate the dom element
if(valueUnwrapped == true) $(element).slideDown(duration);
else $(element).slideUp(duration);
}
};
1、陣列繫結
this.items = ko.observableArray([
{ id: 1, name: "Apple Pie" },
{ id: 2, name: "Pumpkin Pie" },
{ id: 3, name: "Blueberry Torte" }
]);
this.items.push({ id: 4, "Strawberry Shortcake" });
重要是要注意,ObservableArrays跟蹤數組裡的item更改,而不是單獨的一個item的屬性。在上面的例子中,如果你的應用需要跟蹤item的name,那麼name屬性需要也加一個observable。
2、在IE6下,如果有空格要寫 否則不呈現空格。
一、控制文字和展現
1、text繫結
2、visible繫結
3、html繫結
<div data-bind="html: details"></div>
<script type="text/javascript">
var viewModel = {
details: ko.observable() // Initially blank
};
viewModel.details("<em>For further details, view the
report <a href='report.html'>here</a>.</em>"); // HTML content
appears
</script>
4、如果你提供的不是數字或者字串,你傳遞的是物件或陣列等,innerHTML/text bingding和yourParameter.toString()效果一樣。
5、css繫結
<div data-bind="css: { profitWarning: currentProfit() < 0 }">
Profit Information
</div>
<script type="text/javascript">
var viewModel = {
currentProfit: ko.observable(150000) // Positive
value, so initially we don't apply the "profitWarning" class
};
viewModel.currentProfit(-50); // Causes the
"profitWarning" class to be applied
</script>
當currentProfit()<0時,css樣式名"profitWarning"就增加,否則移除這個css。
動態切換兩個css:
<div data-bind="css: profitStatus">
Profit Information
</div>
<script type="text/javascript">
var viewModel = {
currentProfit: ko.observable(150000)
};
// Evalutes to a positive value, so initially we apply the
"profitPositive" class
viewModel.profitStatus = ko.computed(function() { //
computed
return this.currentProfit() < 0 ? "profitWarning" :
"profitPositive";
}, viewModel);
// Causes the "profitPositive" class to be removed and
"profitWarning" class to be added
viewModel.currentProfit(-50);
</script>
可以同時使用多個css繫結:
<div data-bind="css: { profitWarning: currentProfit() < 0, majorHighlight: isSevere }">
當類標誌不合法時,如profitWarning,給其加上引號:'profitWarning'
6、style 繫結
<div data-bind="style: { color: currentProfit() < 0 ? 'red' :
'black', fontWeight: isSevere() ? 'bold' : '' }">...</div>
7、attr繫結
<a data-bind="attr: { href: url, title: details }">
Report
</a>
<script type="text/javascript">
var viewModel = {
url: ko.observable("year-end.html"),
details: ko.observable("Report including final year-
end statistics")
};
</script>
attr屬性名字不合法時,加上引號就可以。
二、控制流繫結
1、foreach繫結
foreach繫結複製進入一個數組的標記部分,繫結每一個複製標記到相應的陣列條目。可以和其他控制流的if、with一起使用。
<h4>People</h4>
<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>
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());
$index:序號
$parent:上一級元素
(1)$data
foreach塊可以在陣列項引用屬性,但是如果希望在陣列條目本身時引入屬性:
用$data代表每一項。
顯示每一項的具體內容:
<td data-bind="text: $data.firstName"></td>
(2)別名:as,加上引號,是給一個新名字為新的變數,不是改變值。
任何foreach迴圈內部,都會引用別名進入現在的陣列條目。這在祖先元素已經巢狀foreach塊,而且你需要在更高一層引用一個條目宣告時很有用。
<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>
<script>
var viewModel = {
categories: ko.observableArray([
{ name: 'Fruit', items: [ 'Apple', 'Orange',
'Banana' ] },
{ name: 'Vegetables', items: [ 'Celery', 'Corn',
'Spinach' ] }
])
};
ko.applyBindings(viewModel);
</script>
(3)只有部分元素迴圈遍歷,加上包裹元素在內部(如例子中的span標籤)。使用<!---->
<ul>
<li class="header">Header item</li>
<!-- ko foreach: myItems -->
<li>Item <span data-bind="text: $data"></span></li>
<!-- /ko -->
</ul>
<script type="text/javascript">
ko.applyBindings({
myItems: [ 'A', 'B', 'C' ]
});
</script>
(4)想要顯示銷燬的條目,使用includeDestroyed
<div data-bind='foreach: { data: myArray, includeDestroyed:
true }'>
...
</div>
(5)執行動畫效果
afterRender/afterAdd/beforeRemove/beforeMove/afterMove
<ul data-bind="foreach: { data: myItems, afterAdd:
yellowFadeIn }">
<li data-bind="text: $data"></li>
</ul>
<button data-bind="click: addItem">Add</button>
<script type="text/javascript">
ko.applyBindings({
myItems: ko.observableArray([ 'A', 'B', 'C' ]),
yellowFadeIn: function(element, index, data) {
$(element).filter("li")
.animate({ backgroundColor: 'yellow' },
200)
.animate({ backgroundColor: 'white' },
800);
},
addItem: function() { this.myItems.push('New item'); }
});
</script>
afterRender: 在foreach塊複製到文件中或foreach初始化,或新的條
目增加到陣列中,konckout將會提供如下引數到回撥函式中:
插入到陣列中的dom元素
對應被繫結的資料條目
afterAdd:當新條目增加到陣列中時激發。一般用來回調一個方法,比如$().fadeIn(),得到動畫過度當條目增加時。knockout會提供如下引數:
被增加的dom節點,增加的陣列元素index,增加的陣列元素
beforeMove:當陣列條目在陣列中的位置發生改變,且在對應dom節點被移除前 被激發。它適用於所有序號改變的陣列元素,所以當你插入一個數組條目在陣列中,回撥函式會激發其他元素,知道他們的序號位置已經增加了1。可以使用beforeMove來儲存收影響元素的原始螢幕座標。這樣你可以使他們在afterMove回撥函式中動畫過度。
提供的回撥引數:
將要移動的dom節點,移動的陣列元素的序號,移動的陣列元素。
afterMove:當陣列中的陣列條目已經改變位置時,在foreach已經更新dom來匹配之後,被激發。
afterMove適用於所有序號被改變的陣列元素,回撥函式會激發其他元素,直到他們的序號位置都已經增加一。
konockout提供的回撥引數:
將要被移除的dom節點,移動的陣列元素的序號,移動的陣列元素。
2、if繫結
if和visible
if和visible差不多。不同在於,使用visible,包括標籤保持在dom中,經常使用data-bind屬性——visible繫結使用css來切換標籤的可見性。if只在表示式為真的情況下適用於增加或移除dom中繫結的後代元素包括的標籤。
例子:
<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>
<script>
ko.applyBindings({
planets: [
{ name: 'Mercury', capital: null },
{ name: 'Earth', capital: { cityName: 'Barnsley' }
}
]
});
</script>
在以上例子中,因為if,capital為null就不用繼續執行,發生錯誤:
計算後續capital.cityName不存在的屬性了。在javascript中,可以判斷if:capital判斷是否為空,但是不允許計算為空的值:
capital.cityName。
if後面的語句為true,顯示包含的標籤。
if後面的語句為false,包含的標籤將會從document中移走而不是適用於任何剛開始的繫結。
如果表示式提及到任何可觀測值,當它們改變時表示式會被重新計算。
相應的,帶有if標籤塊將會動態增加和移除當表示式結果發生改變時。
data-bind屬性將會被用於一個新的副本包含標籤。
當想要實現控制某一部分標籤顯示隱藏,
使用<!-- ko --><!-- /ko -->
<ul>
<li>This item always appears</li>
<!-- ko if: someExpressionGoesHere -->
<li>I want to make this item present/absent
dynamically</li>
<!-- /ko -->
</ul>
3、ifnot繫結
和if一樣。完全可以用if代替。
4、with繫結
with繫結建立了一個新的上下文,所以後代元素被繫結一個詳細的物件上下文。
可以任意使用其他控制流繫結如if/foreach和巢狀with繫結。
以下是一個簡單的切換繫結上下文到子物件。
注意data-bind屬性,沒有必要加上latitude和longitude的字首
coords.。因為繫結上下文已經切換到coords了。
<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>
<script type="text/javascript">
ko.applyBindings({
city: "London",
coords: {
latitude: 51.5001524,
longitude: -0.1262362
}
});
</script>
複雜一點的with例子:
<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>
function AppViewModel() {
var self = this;
self.twitterName = ko.observable('@example');
self.resultData = ko.observable(); // No initial value
self.getTweets = function() {
var name = self.twitterName(),
simulatedResults = [
{ text: name + ' What a nice day.' },
{ text: name + ' Building some cool apps.' },
{ text: name + ' Just saw a famous celebrity
eating lard. Yum.' }
];
self.resultData({ retrievalDate: new Date(),
topTweets: simulatedResults });
}
self.clearResults = function() {
self.resultData(undefined);
}
}
ko.applyBindings(new AppViewModel());
with繫結動態增加移除後代元素依賴於聯絡的值是null/undefined或非空。
如果需要訪問父元素繫結的上下文中的data/functions,可以使用
$parent和root。
關於with的子屬性設定的兩種寫法:
1、寫在viewmodel物件中
var viewModel ={
lcon: {
lname: "lfwefw ",
showCon: [
{ name: "s", textInput: "second" },
{ name: "t", textInput: "third" },
{ name: "f", textInput: "first" }]
}
}
2、用建立viewModel函式的寫法
function AppViewModel() {
var self = this;
self.resultData({ retrievalDate: new Date(), topTweets:
simulatedResults });
}
與其他沒有包括標籤一樣:
<ul>
<li>Header element</li>
<!-- ko with: outboundFlight -->
...
<!-- /ko -->
<!-- ko with: inboundFlight -->
...
<!-- /ko -->
</ul>
例子:
<html>
<head><title></title>
<script type="text/javascript" src="js/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="js/jquery.tmpl.js"></script>
<script type="text/javascript" src="js/knockout-3.1.0.js"></script>
<script type="text/javascript" src="js/knockout.simpleGrid.js"></script>
<style type="text/css">
</style>
</head>
<body>
<form data-bind="submit: showDetail">
<div>
Your Account:<input type="text" data-bind="value: inputCon" />
<button type="submit">提交資訊</button>
</div>
</form>
<div data-bind="visible: hiddenDetail">
<div data-bind="text: inputCon"></div>
<div data-bind="with: lcon">
<div data-bind="text: lname"></div>
<div data-bind="foreach: showCon">
hello:<span data-bind="text: name"></span>
<span data-bind=" text: name"></span>
<br />
</div>
</div>
<button type="submit" data-bind="click: clearCon">隱藏</button>
</div>
<script type="text/javascript">
var viewModel = {
inputCon: ko.observable("@mail"),
showDetail: ko.observable(true),
hiddenDetail: ko.observable(false)
,
lcon: {
lname: "lfwefw ",
showCon: [
{ name: "s", textInput: "second" },
{ name: "t", textInput: "third" },
{ name: "f", textInput: "first" }]
}
};
viewModel.showDetail = function () { viewModel.hiddenDetail(true); }
viewModel.clearCon = function () { viewModel.hiddenDetail(false); }
ko.applyBindings(viewModel);
</script>
</body>
</html>