foreach綁定對於數組中的每個元素複製一節標記語言,也就是html,而且將這節標記語言和數組裏面的每個元素綁定。當咱們呈現一組list數據,或者一個表格的時候,十分有用。javascript
若是你綁定的數組是一個"監控數組" ,observable array,(和wpf裏面的ObservableCollection<T>差很少)。當你添加或移除,或者從新排序數組裏面的元素的時候,會動態的更新UI界面。而且此時並不會影響原先的DOM元素。這樣比咱們直接從新生成一個數組而且綁定元素高效的多。html
固然,foreach也支持嵌套綁定,或者和其餘工做流綁定例如if 或者with。java
對數組中的每個元素生成一行數據的只讀表。jquery
@{ Layout = null; } <script src="~/Scripts/jquery-1.10.2.js"></script> <script src="~/Scripts/knockout-3.2.0.js"></script> <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>
效果以下:數組
First name | Last name |
---|---|
Bert | Bertington |
Charles | Charlesforth |
Denise | Dentiste |
下面這個例子展現了,若是你綁定的數組是一個監控數組,那麼這個UI界面將會和數組的改變同步。app
dom
@{ Layout = null; } <script src="~/Scripts/jquery-1.10.2.js"></script> <script src="~/Scripts/knockout-3.2.0.js"></script> <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> <script type="text/javascript"> 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()); </script>
主參數函數
給foreach傳過去你但願迭代的數組。對於每個數組元素foreach綁定會輸出一段超文本標記語言。post
你也能夠給foreach綁定傳遞一個含有data屬性的 的你想要去迭代的javascript字面量,這個字面量也能夠有其它屬性, 例如 afterAdd
或者includeDestroyed
,能夠看接下來的例子。優化
若是你綁定的是一個監控數組,對數組內容的增長或者移除foreach綁定將會在UI界面上增長或者移除dom元素。
其它參數
就像在上面的例子中展現的。foreach綁定可以指向數組每一條數據的屬性。例如例1中的firstName 和lastName.可是,若是咱們想指向數組自己,應該怎麼辦,此時咱們能夠用$.data.在foreach綁定中,$data指的就是數組的當前的元素項。
@{ Layout = null; } <script src="~/Scripts/jquery-1.10.2.js"></script> <script src="~/Scripts/knockout-3.2.0.js"></script> <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前綴
.例如,你也能夠在例1中像下面這樣寫,雖然這樣寫不必,由於它的默認上下文就是$data
:
<td data-bind=
"text: $data.firstName"
></td>
|
就像咱們在例2 中看到的那樣。你可一用$index 來表示數組中當前項從零開始的索引。 $index是一個監控屬性,當數組的項變動的時候$index也會自動更新。
一樣,你也能夠用$parent來指向foreach外的數據。若是foreach對應的是viewmodel的直接子元素,那麼$parent就是指的viewmodel
<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>
更多關於 $index和$parent的資料能夠去看 binding context properties.
就想在要點1裏面描述的那樣。咱們能夠引用每個數組項用 $data
上下文變量。但在一些特殊狀況下,給當前項一個別名用起來更方便。尤爲在多層嵌套結構中:
別名使用的語法以下:
<ul data-bind="foreach: { data: people, as: 'person' }"></ul>
如今在foreach循環的任何地方,綁定均可以根據person指向當前people的數組項。這種語法在多層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>
注意: 記得經過as給別名 賦值的時候,傳過去一個字符串'category'
, 不是as: category
), 由於咱們是要給變量起一個別名,而不是傳遞一個標識符變量過去。
在一些狀況下,你想要經過foreach綁定一段標記語言html,可是沒有供foreach綁定的元素。例以下面這張情景:
<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>
這種狀況下沒有任何元素可供foreach綁定。你不能放到ul裏面,由於這時候會把header也放到複製的循環裏面去。你也不能放其它的元素在ul裏面,由於ul裏面只容許放<li>元素。
要想處理這種狀況。咱們能夠用無容器綁定語法。這中狀況是依賴於html的註釋標籤。以下:
<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 -->
註釋做爲標籤的開始和結束,定義了一個虛元素來包含咱們須要重複引用的標記語言在裏面,knockout理解這種虛元素語法。咱們能夠就當真的有一個html元素來使用它。
當你修改綁定煮熟的值時,例如增長刪除移動, foreach綁定用一個有效的區分語法來檢測出哪一項被改變了。因此,可以去改變預知匹配的dom元素,這覺得着knockout能夠處理任意的和並和同時的改變
foreach
將會根據咱們的模板繪製一個新的dom元素想插入到原先的dom元素中。foreach
將會移除相關的dom元素。foreach
將只會移動相關的dom元素。注意,從新排列時候的排列不是確定的:須要確保咱們的元素想操做足夠快。,它被優化只是檢測少許的數組項變更。當同時變更的元素不少的時候,knockout會選擇執行刪除而後從新的添加的方式,而不是隻是移動dom元素。
有時你想要將一個數組項標記爲刪除, 但並非真的刪除. 這就是咱們所說的「非毀滅式刪除」. 對於更多的資料能夠看the destroy function on observableArray
.
默認的foreach 綁定將會只是將被刪除的項隱藏。若是你想看並不是真正被刪除的項,你能夠用 includeDestroyed參數
. 例如
<div data-bind='foreach: { data: myArray, includeDestroyed: true }'>
...
</div>
若是咱們想在生成dom元素的時候添加更多自定義的邏輯咱們能夠用,afterRender
/afterAdd
/beforeRemove
/beforeMove
/afterMove
這些回調函數
注意: 這些回調函數時爲了生成list改變的時候的動畫。對於一些跟複雜的需求,咱們能夠用自定義綁定 custom binding 。
@{ Layout = null; } <script src="~/Scripts/jquery-1.10.2.js"></script> <script src="~/Scripts/jquery.color-2.1.2.js"></script> <script src="~/Scripts/knockout-3.2.0.js"></script> <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 模板元素被插入document 的時候被調用。第一次初始化和後續每次添加的時候都會調用這個回調函數。會傳遞下面的參數給回調函數:
afterAdd
—和 afterRender很像
,不過只有增長元素的時候被調用,第一次初始化的時候不會被調用.經常使用來執行元素的淡入$(domNode).fadeIn()
該函數接收下列參數:
beforeRemove
—當一個數組元素被移除,可是相關的dom元素尚未被移除的時候調用,. a beforeRemove
經常使用來執行dom節點的淡出. $(domNode).fadeOut()
這種狀況下knockout不知道你要設置多久的淡出時間,因此對於元素的移除,要在該回調函數裏面手動移除。該函數接收如下參數:
beforeMove
—當一個數組元素改變了位置,可是相關的dom元素尚未被移動的時候執行. 注意beforeMove 將會對全部索引改變的數組元素有效。
因此,若是你在數組元素的開始位置插入一項,那麼aftermove回調函數會對全部的元素有效。由於全部元素的索引都加1改變。咱們能夠用. beforeMove
來記錄爲移動前元素值,而後在aftermove中使用.該回調函數接收如下參數:
afterMove
—在數組元素的位置被改變後調用, 而且是在foreach更新了dom元素後調用 注意afterMove 將會對全部索引改變的數組元素有效。
因此,若是你在數組元素的開始位置插入一項,那麼aftermove回調函數會對全部的元素有效。由於全部元素的索引都加1改變。該回調函數接收如下參數:
更多的例子afterAdd
and beforeRemove
請看 animated transitions.
knockout分頁demo: http://www.cnblogs.com/santian/p/4342777.html
KnockOut官網:http://knockoutjs.com/documentation/foreach-binding.html
本文地址:http://www.cnblogs.com/santian/p/4379445.html
博客地址:一天兩天三天