Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I get the observable array I'm foreach-ing over inside?

It's probably best to explain with an example. This is an example linked from the Knockout blog on how to use $parent. However, in this case, $parent is apparently the same as $root, so I'm having trouble seeing the benefit.

Where it says $parent.lastUpdated, I'd like to instead access the observable array, this.products. I realize I could say $root.products. However, I'd like to generalize this, rather than write it explicitly for every list.

I will actually be using this in conjunction with ko.contextFor.

like image 626
Matthew Flaschen Avatar asked Mar 09 '12 17:03

Matthew Flaschen


People also ask

Does forEach return any value?

forEach() executes the callbackFn function once for each array element; unlike map() or reduce() it always returns the value undefined and is not chainable.

How can you store values from forEach loop into an array in typescript?

Declare the $items array outside the loop and use $items[] to add items to the array: $items = array(); foreach($group_membership as $username) { $items[] = $username; } print_r($items); Hope it helps!!

What is observable array in knockout JS?

An observableArray just tracks which objects it holds, and notifies listeners when objects are added or removed.


1 Answers

You can't get access (generically) to the observableArray that is being looped over directly inside of the foreach loop.

$root and $parent is about the scope, so it will just give you the object that contains the observableArray.

However, you can take advantage of this by ensuring that the scope is your observableArray by using the with binding.

If you just need the underlying array, then you can do:

<div data-bind="with: products">
    <ul data-bind="foreach: $data">
        <li>
            <strong data-bind="text: name"></strong>
            &mdash;
            Array length: <em data-bind="text: $parent.length"></em>
        </li>
    </ul>
</div>​

If you really need the observableArray, then you need to make sure that it has not been unwrapped (in the above example $data is unwrapped already). To do this, you can normalize the name of the array and look for it in your template like:

<div data-bind="with: { theArray: products }">
    <ul data-bind="foreach: theArray">
        <li>
            <strong data-bind="text: name"></strong>
            &mdash;
            Array length: <em data-bind="text: $parent.theArray().length"></em>
        </li>
    </ul>
</div>​

Here is a sample: http://jsfiddle.net/rniemeyer/T6JvV/

If you can't live with the extra div, then you can certainly use the containerless control-flow bindings like:

<!-- ko with: { theArray: products } -->
    <ul data-bind="foreach: theArray">
        <li>
            <strong data-bind="text: name"></strong>
            &mdash;
            Array length: <em data-bind="text: $parent.theArray().length"></em>
        </li>
    </ul>
<!-- /ko -->
like image 114
RP Niemeyer Avatar answered Sep 27 '22 10:09

RP Niemeyer