jQuery递归附加模板

时间:2013-11-07 07:00:47

标签: javascript jquery recursion handlebars.js

我正在尝试使用Handlebars.js和递归构建树结构:

/**
 * Clear the categories container and render the roots
 */
function renderTree(json)
{
    $categories.html('');
    $.each(json, function(){
        renderBranch(null, this);
    });
}

/**
 * Render a branch and its children recursively passing the parent element
 */
function renderBranch(parent, branch)
{
    var data = {
        id: branch.identifier,
        label: branch.text
    };

    // If parent is null, it's a root, use the root template
    if (null == parent) {
        parent = $categories;
        template = $(templates.root({category: data}).replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g,'').replace(/\s+/g,' '));
    } else {
        // it not a root, user the standard category template
        template = $(templates.branch({category: data}).replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g,'').replace(/\s+/g,' '));
    }

    // if the category has children, append a child element and fill it with the children
    if (ObjectLength(branch.children) > 0) {
        var child = $("<ul></ul>").addClass('child').appendTo(template);
        $.each(branch.children, function(){
            renderBranch(child, this);
        });
    }

    // Finally append the current template to the parent one
    template.appendTo(parent);
}

以下是我的Handlebars.js模板:

<script id="root-template" type="text/x-handlebars-template">
    <ul class="category-tree" style="margin: 0 5px 20px 0;padding:5px;border-radius: 2px;background-color:#e1ebff;width:30%;">
        <span class="title selectable" data-id="{{ category.id }}" data-label="{{ category.label }}" style="font-weight:bold">{{ category.label }}</span>
    </ul>
</script>

<script id="branch-template" type="text/x-handlebars-template">
    <li>
        <span class="selectable" data-id="{{ category.id }}" data-label="{{ category.label }}">{{ category.label }}</span>
    </li>
</script>

我最终得到了树的叶子,所以递归正在起作用,但子模板没有附加到父模板,而父模板没有附加到父...等等。

我最终得到以下DOM:

<div class="categories" style="float: left; width: 100%; margin-bottom: 40px; position: relative; height: 0px;">
    <li><span class="selectable" data-id="8" data-label="Classic and Antique Car">Classic and Antique Car</span></li>
    <li><span class="selectable" data-id="36" data-label="Vocational Schools">Vocational Schools</span></li>
    <li><span class="selectable" data-id="361" data-label="Mexican">Mexican</span></li>
    <li><span class="selectable" data-id="85" data-label="Cardiologists">Cardiologists</span></li>
    <li><span class="selectable" data-id="410" data-label="Canoes and Kayaks">Canoes and Kayaks</span></li>
    <li><span class="selectable" data-id="151" data-label="Candy Stores">Candy Stores</span></li>
    <li><span class="selectable" data-id="421" data-label="Car and Truck Rentals">Car and Truck Rentals</span></li>
    <li><span class="selectable" data-id="437" data-label="Lodges and Vacation Rentals">Lodges and Vacation Rentals</span></li>
    <li><span class="selectable" data-id="446" data-label="Career Counseling">Career Counseling</span></li>
</div>

有人看到我错了吗? 干杯, 马克西姆

1 个答案:

答案 0 :(得分:0)

我发现:)我认为我必须在函数中声明template,以便将其视为局部变量。

    function renderTree(json)
    {
        $categories.html('');
        $.each(json, function(){
            renderBranch(null, this);
        });
    }

    function renderBranch(parent, branch)
    {
        var data = {
            id: branch.id,
            label: branch.labels.en
        };

        var template = $(templates.branch({category: data}).replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g,'').replace(/\s+/g,' '));

        if (null == parent) {
            parent = $categories;
            template = $(templates.root({category: data}).replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g,'').replace(/\s+/g,' '));
        }

        if (ObjectLength(branch.children) > 0) {
            var child = $("<ul></ul>").addClass('child').appendTo(template);
            $.each(branch.children, function(){
                renderBranch(child, this);
            });
        }

        template.appendTo(parent);
    }