Dan Lister
Dan Lister

Reputation: 2583

KnockoutJS: Using nested conditional if statements for virtual elements

I'm wanting to use virtual elements to loop through a collection but only if the collection exists within the view model. My original guess would be to add a virtual if followed by a virtual foreach as follow:

<!-- ko if: items -->
    <!-- ko foreach: items -->
        <span data-bind="text: $data"></span>
    <!-- /ko -->
<!-- /ko -->

With the given view model, my view model correctly binds if the collection exists. But for some reason, if it does not, KnockoutJS throws an exception saying that my collection is not defined. This makes sense except when I take the foreach statement out. The if statement then works as excepted and does not bind if the collection does not exist. I've given a better example at http://jsfiddle.net/danlister/qhL7e/.

Upvotes: 1

Views: 7035

Answers (2)

Rynan
Rynan

Reputation: 481

Your fiddle provides two different problems.

First Problem

The first lies with the fact that items is an observableArray. Because of this fact when you test on

<!-- ko if: items -->

it will always return true because an observableArray is simply a function call. To fix this problem, you could check if the array is empty, because you know the items array will always be there, such as

<!-- ko if: items().length !== 0 -->

Second Problem

The second Problem (referencing the noitems array in your fiddle) can't be done as far as my knowledge goes. This is due to the fact that upon applying the bindings the first time to the page, it computes all if statements and will only update them if one of the observable variables changes. Since the array wasn't there at creation, it will never be re-evaluated.


I have created a fiddle to showcase both of the cases: http://jsfiddle.net/Rynan/3UMTM/. Notice how "test" goes away when you remove all elements in the array for the first problem and how "Taa-daa" never appears when you switch the noitems boolean even though the text updates.

Upvotes: 4

Simon
Simon

Reputation: 2830

The problem lies with this...

<!-- ko if: noitems -->
    <!-- ko foreach: noitems -->
        <span data-bind="text: $data"></span>
    <!-- /ko -->
<!-- /ko -->

You need to define a noitems member in your view model.

EDIT

You could probably do something like this to get around it - I haven't tried it.

<!-- ko if: noitems -->
    <!-- ko foreach: noitems && noitems() -->
        <span data-bind="text: $data"></span>
    <!-- /ko -->
<!-- /ko -->

Upvotes: 0

Related Questions