KnockoutJS 3.X API 第四章之數據控制流foreach綁定
foreach綁定
foreach綁定主要用于循環(huán)展示監(jiān)控數組屬性中的每一個元素,一般用于table標簽中
假設你有一個監(jiān)控屬性數組,每當您添加,刪除或重新排序數組項時,綁定將有效地更新UI的DOM-插入或去除相關項目或重新排序現(xiàn)有的DOM元素,不影響任何其他的DOM元素。
當然,也可以配合其他控制流一起適用,例如if和with。
示例1:遍歷監(jiān)控屬性數組
本例適用foreach綁定,在一個table標簽中循環(huán)顯示監(jiān)控屬性數組的內容
<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:添加或刪除項目
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
如前兩個示例中,foreach后面所跟的是要循環(huán)的監(jiān)控屬性數組名稱,而foreach內部所跟隨的是監(jiān)控屬性數組的項目,例如firstName和lastName。
當你想引用監(jiān)控屬性數組本身的時候,就可以使用這個特殊的上下文$data,他所指的就是監(jiān)控屬性數組本身。
例如,你的監(jiān)控屬性數組中的項目沒有明確的項目名稱:
<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)控數組屬性中的項目,例如:
<td data-bind="text: $data.firstName"></td>
其實這是多此一舉的。因為firstName的默認前綴就是$data,所以一般可以省略不寫。
備注2:使用$index、$parent和其他的上下文標記
你可能會發(fā)現(xiàn),在示例2中使用了$index來代替了監(jiān)控屬性數組的索引值(從0開始),當然$index是一個監(jiān)控屬性,他會根據數據的變化而自動變化,就像示例2中展示的一樣。
而$parent所代表的是在foreach綁定循環(huán)外的某個綁定屬性,例如:
<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綁定項目起個別名
在備注1中,使用$data.varibale的方式訪問的監(jiān)控屬性數組的項目,但在有些時候你可以需要給這些項目起個別名,那就是可以使用as,例如:
<ul data-bind="foreach: { data: people, as: 'person' }"></ul>
現(xiàn)在,只要在foreach循環(huán)中,使用person,就可以訪問數組中的元素了。
也有些嵌套使用的例子,這中會更加復雜一些,例如:
<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容器并生產內容
在某些情況下,可能需要復制容器標簽的內容,例如生成如下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標簽中使用foreach綁定,解決這個問題的方法就是使用無容器的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:檢測并處理數組變化
當您修改模型數組的內容(通過添加,移動或刪除其項),在foreach綁定使用一個有效的差分算法計算方法當出發(fā)生了什么變化的時候。
當您添加數組項,foreach會使您的模板的新副本,并將其插入到現(xiàn)有的DOM
當你刪除數組項,foreach將直接刪除相應的DOM元素
當你重新排序數組項(保持相同的對象實例),foreach通常只要將相應的DOM元素融入自己的新位置
備注6:銷毀項目
有時你可能想為數據項目做刪除標記,但實際上并不真正刪除該項目。這中方式被稱為非破壞性的刪除。
默認情況下,foreach綁定將跳過(即隱藏)標記為刪除任何數組項。如果你想顯示這些項目,使用includeDestroyed選項。例如,
<div data-bind='foreach: { data: myArray, includeDestroyed: true }'> ... </div>
備注7:使用動畫過渡,提高用戶體驗
如果您需要在生成的DOM元素運行一些定制邏輯,你可以使用afterRender/ afterAdd/beforeRemove/ beforeMove/ afterMove這些回調函數。
下面是一個使用afterAdd的一個簡單的例子,應用經典的“黃色淡出”的效果,以新增項目。它需要的jQuery插件的顏色,使背景色彩的動畫。
源碼如下:
<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>
一些具體的細節(jié)
afterRender-當foreach第一次初始化執(zhí)行的回調函數。KO提供下列參數回調:
插入的DOM元素的數組
數據項
afterAdd-當foreach添加新項目后的回調函數。KO提供下列參數回調:
DOM節(jié)點
添加的數組元素的索引
添加的數組元素
beforeRemove-當一個數組項已被刪除的回調函數。這里最明顯的用jQuery的$(domNode).fadeOut()動畫去除相應的DOM節(jié)點。KO提供下列參數回調:
刪除一個DOM節(jié)點
被刪除的數組元素的索引
刪除的數組元素
beforeMove-當一個數組項在數組中已經改變了位置的回調函數,但之前相應的DOM節(jié)點已被移動。需要注意的是beforeMove適用于所有的數組元素的指標發(fā)生了變化,因此,如果你在一個數組的開頭插入一個新的項目,然后回調(如果指定)將觸發(fā)所有其他元素,因為它們的索引位置增加了一個。您可以使用beforeMove存儲在受影響元素的原始屏幕坐標,這樣你可以在afterMove回調動畫動作。KO提供下列參數回調:
可能是移動的DOM節(jié)點
移動的數組元素的索引
移動的數組元素
afterMove-數組項在數組中已經改變位置的回調函數,KO提供下列參數回調:
可能已經移動的DOM節(jié)點
移動的數組元素的索引
移動的數組元素
以上所述是小編給大家介紹的KnockoutJS 3.X API 第四章之數據控制流foreach綁定,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!
- knockoutjs模板實現(xiàn)樹形結構列表
- 使用asp.net mvc,boostrap及knockout.js開發(fā)微信自定義菜單編輯工具(推薦)
- Asp.net MVC利用knockoutjs實現(xiàn)登陸并記錄用戶的內外網IP及所在城市(推薦)
- KnockoutJS 3.X API 第四章之表單textInput、hasFocus、checked綁定
- KnockoutJS 3.X API 第四章之數據控制流with綁定
- KnockoutJS 3.X API 第四章之事件event綁定
- KnockoutJS 3.X API 第四章之表單value綁定
- BootstrapTable+KnockoutJS相結合實現(xiàn)增刪改查解決方案(三)兩個Viewmodel搞定增刪改查
- KnockoutJS數組比較算法實例詳解
相關文章
JS獲取今天是本月第幾周、本月共幾周、本月有多少天、是今年的第幾周、是今年的第幾天的示例代碼
這篇文章主要介紹了JS獲取今天是本月第幾周、本月共幾周、本月有多少天、是今年的第幾周、是今年的第幾天,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2018-12-12