I have a multidimensional associative array.
this.items = ko.observableArray([
{ name: "name1", viewable: true, children: [
{ name: "name1-1", viewable: true, children: []},
{ name: "name1-2", viewable: false, children: []}
] },
{ name: "name2", viewable: false, children: [] },
{ name: "name3", viewable: true, children: [
{ name: "name3-1", viewable: true, children: []},
] },
{ name: "name4", viewable: true, children: [] }
]);
The goal is to loop through this array and print out only the values that have 'viewable' set to true.
I have this working using a bunch of if and foreach statements, but the code is starting to get out of hand. This example only covers 2 levels buy my array can get up to 5 levels deep , so this code is going to multiply and get ugly really quick .
<ul data-bind="foreach: items">
<!-- ko if: viewable -->
<li data-bind="text: name"></li>
<!-- ko foreach: children -->
<!-- ko if: viewable -->
<li data-bind="text: name"></li>
<!-- /ko -->
<!-- /ko -->
<!-- /ko -->
</ul>
So is there an easier/better way to loop through the entire array?
Underscore.js has some nice method working with arrays maybe you can use flatten and filter to create one array from your structure then you can just write one foreach
:
Or you could use templates to encapsulate your if: viewable
logic and apply the template recursively:
<script type="text/html" id="template">
<!-- ko if: viewable -->
<li data-bind="text: name"></li>
<!-- ko template: { name: 'template', foreach: $data.children } -->
<!-- /ko -->
<!-- /ko -->
</script>
<ul data-bind="template: { name: 'template', foreach: items } ">
</ul>
Demo JSFiddle.
What you need is a template:
<script type="text/html" id="ItemTemplate">
<!-- ko if: viewable -->
<li data-bind="text: name"></li>
<!-- ko template: { name: 'ItemTemplate', foreach: children } --><!-- /ko -->
<!-- /ko -->
</script>
And then just:
<ul data-bind="template: { name: 'ItemTemplate', foreach: items }"></ul>
If you add empty children arrays on items you can use template
<ul data-bind="foreach: items">
<idv data-bind="template: {name: 'mytemp'}" />
</ul>
<div data-bind="stopBinding:true">
<div id="mytemp">
<div data-bind="visible :viewable">
<li data-bind="text: name"></li>
<div data-bind="foreach: children">
<div data-bind="template: {name: 'mytemp'}" /></div>
</div>
</div>
</div>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.