使用Knockout'foreach'循环遍历多维数组

时间:2013-04-04 14:50:08

标签: javascript arrays multidimensional-array knockout.js

我有一个多维关联数组。

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: [] }
]);

目标是遍历此数组并仅打印出'visibleable'设置为true的值。

我使用了一堆if和foreach语句,但代码开始失控。这个例子只涵盖了2个级别购买我的阵列可以达到 5级深度,所以这个代码将成倍增加并且变得非常丑陋非常快

<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>

那么循环整个数组会有更简单/更好的方法吗?

JS Fiddle link

3 个答案:

答案 0 :(得分:3)

Underscore.js有一些处理数组的好方法也许您可以使用flattenfilter从您的结构创建一个数组,然后您只需编写一个foreach:< / p>

或者您可以使用模板封装if: viewable逻辑并递归应用模板:

<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>

演示JSFiddle.

答案 1 :(得分:1)

您需要的是一个模板:

<script type="text/html" id="ItemTemplate">
    <!-- ko if: viewable -->
        <li data-bind="text: name"></li>
        <!-- ko template: { name: 'ItemTemplate', foreach: children } --><!-- /ko -->
    <!-- /ko -->
</script>

然后只是:

<ul data-bind="template: { name: 'ItemTemplate', foreach: items }"></ul>

答案 2 :(得分:1)

如果您在项目上添加空子数组,则可以使用template

JSFiddle sample

<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>