Reputation: 2583
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
Reputation: 481
Your fiddle provides two different problems.
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 -->
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
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