首页 > 解决方案 > 淘汰赛动态加载子树

问题描述

我正在尝试使用淘汰赛制作动态加载子树。我的想法是默认只显示根项目。当我单击项目时,它会动态加载子项目(使用 ajax)。当我点击这个子项目时,它会动态加载他们的孩子.....树应该是多级的(至少 5 级)。

知道怎么做吗?

我试图将这些项目保存到 observableArray 中。问题是每次我选择任何根项时,它都有相同的子项。如何为每个父母分配孩子?

me.categories = ko.observableArray();

me.loadCategories = function () {
      api.call("GET", "/api/...").done((result) => {
        me.categories(result);
      });
    };

<div data-bind="foreach: categories">
<ul id="myUL">
<li>
<span class="caret" data-bind="click: $parent.getSubCategories.bind ($data, id()), text: name"></span>
<ul class="nested" data-bind="foreach: $parent.subcategories">
<li>
<span class="caret" data-bind="click: $parentContext.$parent.getSubCategories1.bind ($data, id), text: name"></span>
<ul class="nested" data-bind="foreach: $parentContext.$parent.subcategories1">
<li>
<span class="caret" data-bind="click: $parents[2].getSubCategories1.bind ($data, id), text: name"></span>
<ul class="nested" data-bind="foreach: $parents[2].subcategories1">
<li>
<span data-bind="text: name"></span>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>

标签: knockout.jstreesubtree

解决方案


渲染树的直接方法是以树的形式获取数据,视觉方面也一样。

  • 对于数据存储,我将使用数组数组的数组...
  • 对于可视化,我会使用递归组件

在这个简单的示例中,我仅将 observableArray 用于根项目 = 您的类别。单击任何项​​目后,新的子类别数组将附加在单击的项目之后作为简单的 JavasSript 数组,并使用 刷新整个树valueHasMutated。有点粗糙,但希望你能看到基本原理。

ko.components.register('myList', {
    template: 
      "<ul data-bind='foreach: $data'>" + 
        "<!-- ko if: typeof $data === 'string' -->" +
          "<li data-bind='text: $data, click: $root.expand.bind(null, $parent, $index())'></li>" +
        "<!-- /ko -->" +
        "<!-- ko if: typeof $data !== 'string' -->" +
          "<!-- ko component: {name: 'myList', params: $data} -->" +
          "<!-- /ko -->" +
        "<!-- /ko -->" +
      "</ul>"
});

var data = ko.observableArray([
  "node1",
  "node2",  
  "node3",
]);

var vm = {
  data: data,
  expand: function(parentArray, i) {
    var fakeAjaxData = ["node1", "node2", "node3"];
    parentArray.splice(i+1, 0, fakeAjaxData);
    data.valueHasMutated();
  }
}

ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.0/knockout-min.js"></script>
<style>li {cursor: pointer}</style>
<div data-bind='component: {name: "myList", params: data}'></div>


推荐阅读