KnockoutJS 3.X API 第四章之?dāng)?shù)據(jù)控制流foreach綁定
foreach綁定
foreach綁定主要用于循環(huán)展示監(jiān)控?cái)?shù)組屬性中的每一個(gè)元素,一般用于table標(biāo)簽中
假設(shè)你有一個(gè)監(jiān)控屬性數(shù)組,每當(dāng)您添加,刪除或重新排序數(shù)組項(xiàng)時(shí),綁定將有效地更新UI的DOM-插入或去除相關(guān)項(xiàng)目或重新排序現(xiàn)有的DOM元素,不影響任何其他的DOM元素。
當(dāng)然,也可以配合其他控制流一起適用,例如if和with。
示例1:遍歷監(jiān)控屬性數(shù)組
本例適用foreach綁定,在一個(gè)table標(biāo)簽中循環(huán)顯示監(jiān)控屬性數(shù)組的內(nèi)容
<table>
<thead>
<tr><th>First name</th><th>Last name</th></tr>
</thead>
<tbody data-bind="foreach: people">
<tr>
<td data-bind="text: firstName"></td>
<td data-bind="text: lastName"></td>
</tr>
</tbody>
</table>
<script type="text/javascript">
ko.applyBindings({
people: [
{ firstName: 'Bert', lastName: 'Bertington' },
{ firstName: 'Charles', lastName: 'Charlesforth' },
{ firstName: 'Denise', lastName: 'Dentiste' }
]
});
</script>
示例2:添加或刪除項(xiàng)目

UI源碼:
<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());
備注1:使用$data
如前兩個(gè)示例中,foreach后面所跟的是要循環(huán)的監(jiān)控屬性數(shù)組名稱,而foreach內(nèi)部所跟隨的是監(jiān)控屬性數(shù)組的項(xiàng)目,例如firstName和lastName。
當(dāng)你想引用監(jiān)控屬性數(shù)組本身的時(shí)候,就可以使用這個(gè)特殊的上下文$data,他所指的就是監(jiān)控屬性數(shù)組本身。
例如,你的監(jiān)控屬性數(shù)組中的項(xiàng)目沒有明確的項(xiàng)目名稱:
<ul data-bind="foreach: months">
<li>
The current item is: <b data-bind="text: $data"></b>
</li>
</ul>
<script type="text/javascript">
ko.applyBindings({
months: [ 'Jan', 'Feb', 'Mar', 'etc' ]
});
</script>
如何你愿意的話,也可以使用$data來引用監(jiān)控?cái)?shù)組屬性中的項(xiàng)目,例如:
<td data-bind="text: $data.firstName"></td>
其實(shí)這是多此一舉的。因?yàn)閒irstName的默認(rèn)前綴就是$data,所以一般可以省略不寫。
備注2:使用$index、$parent和其他的上下文標(biāo)記
你可能會(huì)發(fā)現(xiàn),在示例2中使用了$index來代替了監(jiān)控屬性數(shù)組的索引值(從0開始),當(dāng)然$index是一個(gè)監(jiān)控屬性,他會(huì)根據(jù)數(shù)據(jù)的變化而自動(dòng)變化,就像示例2中展示的一樣。
而$parent所代表的是在foreach綁定循環(huán)外的某個(gè)綁定屬性,例如:
<h1 data-bind="text: blogPostTitle"></h1> <ul data-bind="foreach: likes"> <li> <b data-bind="text: name"></b> likes the blog post <b data-bind="text: $parent.blogPostTitle"></b> </li> </ul>
備注3:使用“as”給foreach綁定項(xiàng)目起個(gè)別名
在備注1中,使用$data.varibale的方式訪問的監(jiān)控屬性數(shù)組的項(xiàng)目,但在有些時(shí)候你可以需要給這些項(xiàng)目起個(gè)別名,那就是可以使用as,例如:
<ul data-bind="foreach: { data: people, as: 'person' }"></ul>
現(xiàn)在,只要在foreach循環(huán)中,使用person,就可以訪問數(shù)組中的元素了。
也有些嵌套使用的例子,這中會(huì)更加復(fù)雜一些,例如:
<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>
備注4:不使用foreach容器并生產(chǎn)內(nèi)容
在某些情況下,可能需要復(fù)制容器標(biāo)簽的內(nèi)容,例如生成如下DOM:
<ul> <li class="header">Header item</li> <!-- The following are generated dynamically from an array --> <li>Item A</li> <li>Item B</li> <li>Item C</li> </ul>
像這種情況,我們就無法在ul標(biāo)簽中使用foreach綁定,解決這個(gè)問題的方法就是使用無容器的foreach綁定:
<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>
這里使用虛擬元素容器,<!-- ko -->和<!-- /ko -->。就想之前章節(jié)提到的虛擬綁定一樣。
備注5:檢測(cè)并處理數(shù)組變化
當(dāng)您修改模型數(shù)組的內(nèi)容(通過添加,移動(dòng)或刪除其項(xiàng)),在foreach綁定使用一個(gè)有效的差分算法計(jì)算方法當(dāng)出發(fā)生了什么變化的時(shí)候。
當(dāng)您添加數(shù)組項(xiàng),foreach會(huì)使您的模板的新副本,并將其插入到現(xiàn)有的DOM
當(dāng)你刪除數(shù)組項(xiàng),foreach將直接刪除相應(yīng)的DOM元素
當(dāng)你重新排序數(shù)組項(xiàng)(保持相同的對(duì)象實(shí)例),foreach通常只要將相應(yīng)的DOM元素融入自己的新位置
備注6:銷毀項(xiàng)目
有時(shí)你可能想為數(shù)據(jù)項(xiàng)目做刪除標(biāo)記,但實(shí)際上并不真正刪除該項(xiàng)目。這中方式被稱為非破壞性的刪除。
默認(rèn)情況下,foreach綁定將跳過(即隱藏)標(biāo)記為刪除任何數(shù)組項(xiàng)。如果你想顯示這些項(xiàng)目,使用includeDestroyed選項(xiàng)。例如,
<div data-bind='foreach: { data: myArray, includeDestroyed: true }'>
...
</div>
備注7:使用動(dòng)畫過渡,提高用戶體驗(yàn)
如果您需要在生成的DOM元素運(yùn)行一些定制邏輯,你可以使用afterRender/ afterAdd/beforeRemove/ beforeMove/ afterMove這些回調(diào)函數(shù)。
下面是一個(gè)使用afterAdd的一個(gè)簡單的例子,應(yīng)用經(jīng)典的“黃色淡出”的效果,以新增項(xiàng)目。它需要的jQuery插件的顏色,使背景色彩的動(dòng)畫。

源碼如下:
<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>
一些具體的細(xì)節(jié)
afterRender-當(dāng)foreach第一次初始化執(zhí)行的回調(diào)函數(shù)。KO提供下列參數(shù)回調(diào):
插入的DOM元素的數(shù)組
數(shù)據(jù)項(xiàng)
afterAdd-當(dāng)foreach添加新項(xiàng)目后的回調(diào)函數(shù)。KO提供下列參數(shù)回調(diào):
DOM節(jié)點(diǎn)
添加的數(shù)組元素的索引
添加的數(shù)組元素
beforeRemove-當(dāng)一個(gè)數(shù)組項(xiàng)已被刪除的回調(diào)函數(shù)。這里最明顯的用jQuery的$(domNode).fadeOut()動(dòng)畫去除相應(yīng)的DOM節(jié)點(diǎn)。KO提供下列參數(shù)回調(diào):
刪除一個(gè)DOM節(jié)點(diǎn)
被刪除的數(shù)組元素的索引
刪除的數(shù)組元素
beforeMove-當(dāng)一個(gè)數(shù)組項(xiàng)在數(shù)組中已經(jīng)改變了位置的回調(diào)函數(shù),但之前相應(yīng)的DOM節(jié)點(diǎn)已被移動(dòng)。需要注意的是beforeMove適用于所有的數(shù)組元素的指標(biāo)發(fā)生了變化,因此,如果你在一個(gè)數(shù)組的開頭插入一個(gè)新的項(xiàng)目,然后回調(diào)(如果指定)將觸發(fā)所有其他元素,因?yàn)樗鼈兊乃饕恢迷黾恿艘粋€(gè)。您可以使用beforeMove存儲(chǔ)在受影響元素的原始屏幕坐標(biāo),這樣你可以在afterMove回調(diào)動(dòng)畫動(dòng)作。KO提供下列參數(shù)回調(diào):
可能是移動(dòng)的DOM節(jié)點(diǎn)
移動(dòng)的數(shù)組元素的索引
移動(dòng)的數(shù)組元素
afterMove-數(shù)組項(xiàng)在數(shù)組中已經(jīng)改變位置的回調(diào)函數(shù),KO提供下列參數(shù)回調(diào):
可能已經(jīng)移動(dòng)的DOM節(jié)點(diǎn)
移動(dòng)的數(shù)組元素的索引
移動(dòng)的數(shù)組元素
以上所述是小編給大家介紹的KnockoutJS 3.X API 第四章之?dāng)?shù)據(jù)控制流foreach綁定,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- knockoutjs模板實(shí)現(xiàn)樹形結(jié)構(gòu)列表
- 使用asp.net mvc,boostrap及knockout.js開發(fā)微信自定義菜單編輯工具(推薦)
- Asp.net MVC利用knockoutjs實(shí)現(xiàn)登陸并記錄用戶的內(nèi)外網(wǎng)IP及所在城市(推薦)
- KnockoutJS 3.X API 第四章之表單textInput、hasFocus、checked綁定
- KnockoutJS 3.X API 第四章之?dāng)?shù)據(jù)控制流with綁定
- KnockoutJS 3.X API 第四章之事件event綁定
- KnockoutJS 3.X API 第四章之表單value綁定
- BootstrapTable+KnockoutJS相結(jié)合實(shí)現(xiàn)增刪改查解決方案(三)兩個(gè)Viewmodel搞定增刪改查
- KnockoutJS數(shù)組比較算法實(shí)例詳解
相關(guān)文章
npm安裝依賴時(shí)出現(xiàn)Peer Dependencies沖突報(bào)錯(cuò)解決分析
這篇文章主要為大家介紹了npm安裝依賴時(shí)出現(xiàn)Peer Dependencies沖突報(bào)錯(cuò)解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
JavaScript實(shí)現(xiàn)Tab欄切換特效
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)Tab欄切換特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
webpack+vue2構(gòu)建vue項(xiàng)目骨架的方法
本篇文章主要介紹了webpack+vue2構(gòu)建vue項(xiàng)目骨架的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01
一個(gè)XML格式數(shù)據(jù)轉(zhuǎn)換為圖表的例子
這個(gè)例子使用的是轉(zhuǎn)換為VML的語法,換成其他如SVG的語法,就可以轉(zhuǎn)換成為SVG圖形,單元數(shù)量可以任意加。2010-02-02
Google Suggest ;-) 基于js的動(dòng)態(tài)下拉菜單
Google Suggest ;-) 基于js的動(dòng)態(tài)下拉菜單...2006-10-10
opencv 識(shí)別微信登錄驗(yàn)證滑動(dòng)塊位置
這篇文章主要介紹了opencv 識(shí)別微信登錄驗(yàn)證滑動(dòng)塊位置及各自的優(yōu)缺點(diǎn),需要的朋友可以參考下2018-08-08

