Javascript 带敲除js的递归模板

Javascript 带敲除js的递归模板,javascript,html,templates,knockout.js,Javascript,Html,Templates,Knockout.js,是否可以仅使用敲除js创建递归模板 我有一个击倒目标: function FormElementNode(children, text, value) { var self = this; self.children = ko.observableArray(children); self.text = ko.observable(text); self.value = ko.observable(value); } children是FormElementNod

是否可以仅使用敲除js创建递归模板

我有一个击倒目标:

function FormElementNode(children, text, value) {
   var self = this;
   self.children = ko.observableArray(children);
   self.text = ko.observable(text);
   self.value = ko.observable(value);
}   
children是FormElementNode的数组

我想在层次结构列表节点中递归地绘制它及其子节点:

<ul>
   <li>Parent text value:
      Children: 
      <ul>
         <li>Child1 text value</li>
         <li>Child2 text value</li>
   </li>
  • 父文本值: 儿童:
    • Child1文本值
    • Child2文本值

谢谢

Yes KnockOut支持递归模板,因此您可以在模板中引用和呈现相同的模板

您案例中的html示例如下所示:

<script id="formElementNodeTemplate" type="text/html">
<ul>
    <li>Parent <span data-bind="text: text"></span> 
               <span data-bind="text: value"></span>
        <br/>
        Children:
        <!-- ko template: { name: 'formElementNodeTemplate',  
                            foreach: children } -->
        <!-- /ko -->        
     </li>
   </ul>
</script>    

<div data-bind="template: { name: 'formElementNodeTemplate', data: $data }">
</div>

  • 母公司
    儿童:

演示

我想,我有一个更好的解决方案,没有树根。请看一看:

模板:

<script id="treeElement" type="text/html">
    <li>
        <span data-bind="text: name"></span>
        <ul data-bind="template: { name: 'treeElement', foreach: children }">
        </ul>
     </li>
</script>    

<ul data-bind="template: { name: 'treeElement', foreach: $data.treeRoot }"></ul>
var viewModel = {
    treeRoot: ko.observableArray()
};

var TreeElement = function(name, children) {
   var self = this;
   self.children = ko.observableArray(children);
   self.name = ko.observable(name);
}

var tree = [
    new TreeElement("Russia", [
        new TreeElement("Moscow")
    ]),
    new TreeElement("United States", 
    [
        new TreeElement("New York", [ 
            new TreeElement("Harlem"),
            new TreeElement("Central Park")
        ]) 
    ])
];

viewModel.treeRoot(tree);

ko.applyBindings(viewModel);

希望有帮助

这篇文章对我帮助很大。我总是在寻找新的方法来使用淘汰赛。我只是想添加一个有用的修改,这正是nemesv仅使用ko.mapping插件所建议的

//Nested javascript object:
var formElementNode = {
    children: [{
        children: [],
        text: 'Child1',
        value: 'Value1'
    }, {
        children: [{
            children: [{
                children: [],
                text: 'Child2.1.1',
                value: 'Value2.1.1'
            }],
            text: 'Child2.1',
            value: 'Value2.1'
        }],
        text: 'Child2',
        value: 'Value2'
    }, {
        children: [],
        text: 'Child3',
            value: 'Value3'
    }],
    text: 'Main',
    value: 'MainValue'
};

//Use ko.mapping to generate viewModel:
var viewModel = ko.mapping.fromJS(formElementNode);
ko.applyBindings(viewModel);
如本文所示。

递归自定义绑定 另一个解决方案是,在阅读了模板速度较慢的内容后,我正在考虑使用递归绑定

    ko.bindingHandlers.nestMe = {
        init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    
        },
        update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
            var observable = valueAccessor() || { };
            var unwrapped = ko.unwrap(observable);
    
            ko.utils.setHtml(element, '<li>'+unwrapped+'<ul data-bind="foreach: children"><li data-bind="nestMe: name" /></ul></li>');
    
        }
    };
    
    var rootModel = function(name, children) {
        this.name = ko.observable(name);
        this.children = ko.observableArray(children);
    };
    
    var basemodel = new rootModel('test');
    basemodel.children.push(new rootModel('aaa',[new rootModel('111'),new rootModel('222')]));
    basemodel.children.push(new rootModel('bbb'));
    basemodel.children.push(new rootModel('ccc',[new rootModel('333'),new rootModel('444')]));
    
    ko.applyBindings(basemodel);
    
    ko.bindingHandlers.nestMe={
    init:函数(元素、valueAccessor、allBindings、viewModel、bindingContext){
    },
    更新:函数(元素、valueAccessor、allBindings、viewModel、bindingContext){
    var observable=valueAccessor()| |{};
    var unwrapped=ko.Unwrapp(可观察);
    ko.utils.setHtml(元素“
  • ”+unwrapped+”
      • ); } }; var rootModel=函数(名称、子级){ this.name=ko.observable(name); this.children=ko.array(children); }; var basemodel=新的根模型(“测试”); basemodel.children.push(newrootmodel('aaa')、[newrootmodel('111')、newrootmodel('222')); basemodel.children.push(新的rootModel('bbb'); basemodel.children.push(newrootmodel('ccc')、[newrootmodel('333')、newrootmodel('444')); ko.应用绑定(基本模型);
  • 在递归之前有机会处理数据应该很有用


    谢谢您的快速回复。我在模板中有另一个'foreach',我得到了一个错误:“这个模板引擎不支持其模板中的'foreach'绑定”。我应该使用另一个模板来构造嵌套的foreach吗?另一个问题是,我希望子对象是由
  • 表示的兄弟。您提供的当前解决方案为每个孩子打开了一个新的列表(
      )。关于您的antother
      foreach
      问题:我认为您应该在另一个问题中问它,在这个问题中显示您实际的问题代码。关于
      我刚刚提供了一个小样本,如果您有一些特殊需求,您可以在模板周围放置
      ul
      li
      的地方使用它:谢谢!现在开始工作了!关于
      foreach
      问题,当我删除下划线代码时,错误消失了:)@nemesv回答得很好。如何更新代码,以便用户可以在运行时向子项添加项?比如,他/她可以点击一个按钮,然后添加一个新项目。我可以为根而得到它,但不能为孩子?谢谢你的解决方案。这对我很有帮助。你能分享一个关于模板比较慢的资源吗?@Michael可能不是我读到的地方,但这里给出了一个例子: