2012-02-07 88 views
38

我使用下面的模板:Knockout.js - 的foreach綁定 - 測試,如果最後一個元素

<div class="datatypeOptions" data-bind="if: $data.datatypeTemplate().allowOptions"> 
    <h3>Allowed responses</h3> 

    <p data-bind="if: $data.datatypeTemplate().datatypeOptions().length == 0">There are no responses for this question, yet. <a href="#" data-bind="click: function(d, e){$root.addDatatypeOption($data.datatypeTemplate());}">Add one</a> 
    <ul data-bind="foreach: $data.datatypeTemplate().datatypeOptions()"> 
     <li> 
      <a href="#" data-bind="text: name, click: $root.selectedDatatypeOption, visible: $data !== $root.selectedDatatypeOption()"></a> 
      <input data-bind="value: name, visibleAndSelect: $data === $root.selectedDatatypeOption(), event: { blur: $root.clearDatatypeOption }, executeOnEnter: { callback: function(){ $root.addDatatypeOption($parent.datatypeTemplate()); } }" /> 
      //I want to show this a tag only if $data is the last element in the array. 
Problem here ===> <a href="#" data-bind="if: $data == $parent.datatypeTemplate().datatypeOptions()[ $parent.datatypeTemplate().datatypeOptions().length - 1 ], click: function(d, e){$root.addDatatypeOption($data.datatypeTemplate());}"><img src='/static/img/icons/custom-task-wizard/black/plus_12x12.png' title='Add option'></a> 
     </li> 
    </ul> 
</div> 

我得到這個錯誤在控制檯:

Uncaught Error: Unable to parse bindings. 
Message: TypeError: Object [object Object] has no method 'datatypeTemplate'; 
Bindings value: if: $data == $parent.datatypeTemplate().datatypeOptions()[ $parent.datatypeTemplate().datatypeOptions().length - 1 ], click: function(d, e){$root.addDatatypeOption($data.datatypeTemplate());} 

是我加的唯一選擇函數給我的viewmodel,如果傳入的元素在數組中最後一個返回true/false?

+0

http://memegenerator.net/instance/14211604 – Jonathan 2012-02-08 00:32:35

+2

你可能想嘗試重現這的jsfiddle。我注意到的一件事是,你錯過了關閉你的'p'標記,這可能會導致綁定/上下文中的問題。您可以通過在視圖模型上放置一個計算的可觀察值或函數來保持視圖更清晰,以幫助確定最後一項。 – 2012-02-08 02:59:31

回答

0

嘗試以下操作:

  1. 使用$root而不是$parent
  2. 準備的最後一個項目事先和這個項目傳遞給您的模板作爲附加參數。
  3. 封裝最後一個元素爲可觀察。
73

我簡化了這個問題,但是這個jsFiddle演示了一個可能的解決方案。

「如果」 結合:

<div data-bind="if: ($index() === ($parent.data().length - 1))">I'm the last element</div> 

無容器 「如果」 結合:

<!-- ko if: ($index() === ($parent.data().length - 1)) --> 
<div>I'm the last element again</div> 
<!-- /ko --> 

可以使用$index一個foreach內結合來獲得當前的指數裝訂項目。使用它與父級的原始集合進行比較。

有關綁定上下文的更多信息,請參閱HERE

+1

不幸的是,如果你使用'as'選項,'$ data'不是也綁定..只是一個「gotcha」。 – user2246674 2013-05-28 23:30:05

+0

這不適合我,我想也許是B/C我在淘汰賽v 2.2.1。但是,下面的工作(當然,將MyWingDings替換爲數組對象的名稱)。 data-bind =「visible:$ index()<$ parent.MyWingDings.length - 1」 – Sean 2014-10-21 17:17:34

+0

@ user2246674請參閱** [我的答案](http://stackoverflow.com/a/076/4390133)**你正在使用'as'選項 – 2017-04-04 14:29:15

8

我注意到有許多用於增強KO的請求,以支持foreach結合$length$last,或$array保留的屬性,雖然,出於各種原因(往往表現),他們沒有把它做成了代碼庫。

如果任何人有興趣使用自定義綁定爲特定案例公開這些元素,下面是一個簡單示例,顯示$length變量以打印「漂亮」列表。
您只需在任何地方使用forEachWithLength即可使用foreach

​​

實例:

<div data-bind="forEachWithLength: myArray"> 
    <span data-bind="text: $data"></span> 
    <!-- ko if: ($index() < $length-2) -->, <!-- /ko --> 
    <!-- ko if: ($index() === $length-2) --> and <!-- /ko --> 
</div> 

輸入:["One", "Two", "Three", "Four"]

輸出:One, Two, Three and Four

Fiddle

Further reading

2

如果你是使用在foreachas選項結合,然後去most-upvoted answer to this question

如果您是DO使用as運算符在foreach綁定。那麼回答將會不是工作。

這裏是在這種情況下,解決方案

<div data-bind="foreach:{data: Items, as :'item'}"> 
    <div data-bind="if: ($index() === ($parent.Items().length - 1))">I'm the last element</div> 
</div> 

與您使用在我的情況下,它被命名爲Items可觀察到的陣列的名稱替換$parent.data(),所以我取代了$parent.data()與祕密$parent.Items()

注意該解決方案在所有情況下工作,如果你正在使用as選項或無T,
但在第一種情況下它解決了一些最-upvoted答案沒有解決