Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use foreach with a special first element?

If I have an observable array

foos = [{ name: "a" }, { name: "b" }, { name: "c" }]

on my viewmodel, I would like to render the following:

<ul>
  <li class="add-new-foo">Special stuff here</li>
  <li>a</li>
  <li>b</li>
  <li>c</li>
</ul>

I got pretty close with

<ul data-bind="template: { name: 'foo-template', foreach: foos }">
  <li class="add-new-foo">Special stuff here</li>
</ul>

<script id="foo-template" type="text/html">
  <li data-bind="text: name"></li>
</script>

But this ended up putting the .add-new-foo after the a, b, c.

Any ideas? In my case it's crucial to use Knockout foreach instead of jQuery template's {{each}}, because of the benefits mentioned in the Knockout docs.

like image 473
Domenic Avatar asked Mar 20 '11 21:03

Domenic


3 Answers

Looks like it's going to be possible with the new containerless control flow and foreach binding in KO 1.3 2.0:

<ul>
    <li>Static item</li>
    <!-- ko foreach: products -->
        <li data-bind="text: name"></li>
    <!-- /ko -->
</ul>

See this post for details: http://blog.stevensanderson.com/2011/08/31/knockout-1-3-0-beta-available/

like image 200
Jacob Avatar answered Oct 29 '22 10:10

Jacob


As there is not currently a way to tell the template binding where to render the template, I don't see a cleaner way to do it right now other than something like:

<ul data-bind="template: { name: 'foo-template', foreach: foos, templateOptions: { first: foos()[0]} }">
</ul>

<script id="foo-template" type="text/html">
    {{if $item.first === $data}}
    <li class="add-new-foo">Special stuff here</li>
    {{/if}}
    <li data-bind="text: name"></li>
</script>

So, we are passing the first item in your array as templateOptions and checking for if the item that we are dealing with in the template is indeed the first.

Sample here: http://jsfiddle.net/rniemeyer/XuXcr/

Also templateOptions was added after 1.12 KO, so you would need current code. More info about templateOptions here.

Hope this helps.

like image 22
RP Niemeyer Avatar answered Oct 29 '22 10:10

RP Niemeyer


<!-- ko if: $index() == 0 -->
your code
<!-- /ko -->
like image 39
Alexey Avatar answered Oct 29 '22 08:10

Alexey