KnockoutJS和递归模板

时间:2011-11-22 18:32:32

标签: javascript asp.net-mvc-3 knockout.js jquery-templates

我见过this question,并使用其方法在JS控制台Uncaught SyntaxError: Unexpected token )上抛出错误。

我正在尝试使用递归的类别数组,这些类别具有Children属性,这是一个类别数组,并使用jquery模板构建它们。我尝试过的每种方法都会导致语法错误。我已经验证了该对象在javascript中正确显示(它来自MVC3,使用@Html.Raw(Json.Encode(Model.Categories))将其放入JS数组中)。这是原始的csharp类

public class CategoryTreeModel
{
    public int Id { get; set; }
    public string Name{ get; set; }
    public bool Selected { get; set; }
    public bool HasChildren { get { return Children.Count > 0; } }
    public List<CategoryTreeModel> Children { get; set; }
}

这个原始的html调用模板的第一级:

<ul class="nav"  data-bind="template: {name: 'categories_template', foreach: categories}">
        </ul>

和模板本身:

<script type="text/html" id="categories_template">
<li id="category_${Id}" class="category_header">${Name}
   {{if $data.HasChildren }}
        <ul data-bind='template: { name: "categories_template", foreach: Children}'>
        </ul>
   {/if}
</li>      

如果我取出它的子部分,正确渲染第一级,模板就可以工作。当我按原样使用代码时,我得到Uncaught SyntaxError: Unexpected token )。我做错了什么?

2 个答案:

答案 0 :(得分:4)

您的上次{/if}应为{{/if}}

以下是一个示例:http://jsfiddle.net/rniemeyer/vbKVC/

答案 1 :(得分:1)

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

http://jsfiddle.net/nonsense66/Bzekr/

模板:

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

使用Javascript:

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

希望这有帮助