动态嵌套对象数组的递归迭代

7

我正在使用AngularJS,其中一个例子:http://jsfiddle.net/furf/EJGHX/

在更新函数发生时,我需要获取数据并在将其发送到服务器之前添加一些值(如果使用Angular而不是JS进行此操作会更好,请告诉我)。

我试图获取“parentid”和“index”并更新子级。

以下是我正在循环的数据

{
    "children": [{
        "id": "5",
        "parentid": "0",
        "text": "Device Guides",
        "index": "1",
        "children": [{
            "id": "10",
            "index": "0",
            "text": "Grandstream GXP-21XX"
        }, {
            "id": "11",
            "index": "1",
            "text": "Polycom Soundstation/Soundpoint"
        }, {
            "id": "23",
            "index": "2",
            "text": "New Polycom"
        }]
    }, {
        "id": "6",
        "parentid": "0",
        "text": "Pre-Sales Evaluation",
        "index": "0",
        "children": []
    }, {
        "id": "7",
        "parentid": "0",
        "text": "Router Setup Guides",
        "index": "2",
        "children": [{
            "id": "9",
            "index": "0",
            "text": "Sonicwall"
        }, {
            "id": "12",
            "index": "1",
            "text": "Cisco"
        }]
    }, {
        "id": "9",
        "parentid": "7",
        "text": "Sonicwall",
        "index": "0",
        "children": []
    }, {
        "id": "10",
        "parentid": "5",
        "text": "Grandstream GXP-21XX",
        "index": "0",
        "children": []
    }, {
        "id": "11",
        "parentid": "5",
        "text": "Polycom Soundstation/Soundpoint",
        "index": "1",
        "children": []
    }, {
        "id": "12",
        "parentid": "7",
        "text": "Cisco",
        "index": "1",
        "children": []
    }, {
        "id": "15",
        "parentid": "0",
        "text": "Post-Sales Implementation Check List",
        "index": "7",
        "children": [{
            "id": "16",
            "index": "0",
            "text": "Porting and New Number Details"
        }, {
            "id": "18",
            "index": "1",
            "text": "Partner Setup"
        }, {
            "id": "19",
            "index": "2",
            "text": "test"
        }, {
            "id": "21",
            "index": "3",
            "text": "test"
        }]
    }, {
        "id": "16",
        "parentid": "15",
        "text": "Porting and New Number Details",
        "index": "0",
        "children": []
    }, {
        "id": "18",
        "parentid": "15",
        "text": "Partner Setup",
        "index": "1",
        "children": []
    }, {
        "id": "19",
        "parentid": "15",
        "text": "test",
        "index": "2",
        "children": []
    }, {
        "id": "20",
        "parentid": "0",
        "text": "test",
        "index": "11",
        "children": []
    }, {
        "id": "21",
        "parentid": "15",
        "text": "test",
        "index": "3",
        "children": []
    }, {
        "id": "23",
        "parentid": "5",
        "text": "New Polycom",
        "index": "2",
        "children": []
    }, {
        "id": "24",
        "parentid": "0",
        "text": "Test Markup",
        "index": "14",
        "children": []
    }, {
        "id": "25",
        "parentid": "0",
        "text": "test",
        "index": "15",
        "children": []
    }]
}

这是我目前循环遍历它的方式,但它只能获取第一个维度

for (i = 0, l = data.length; i < l; i++) {
    parentid = data[i].id == null ? '0' : data[i].id;
    data[i].index = i;
    if (data[i].children) {
        if (data[i].children.length > 0) {
            for (q = 0, r = data[i].children.length; q < r; q++) {
                data[i].children[q].parentid = parentid;
                data[i].children[q].index = q;
            }
        }
    }
}

我在另一个fiddle上找到了这个,但我不知道如何获取parentid或index

$.each(target.children, function(key, val) { recursiveFunction(key, val) });

    function recursiveFunction(key, val) {
        actualFunction(key, val);
        var value = val['children'];
        if (value instanceof Object) {
            $.each(value, function(key, val) {
                recursiveFunction(key, val)
            });
        }

    }


function actualFunction(key, val) {}
2个回答

7

如果我理解正确,您希望每个“子项”都有一个parentID(由其父项定义;否则为0)和一个index(基于其在兄弟集合中的位置)。

function normalize(parent) {
    if (parent && parent.children) {
        for (var i = 0, l = parent.children.length; i < l; ++i) {
            var child = parent.children[i];
            child.index = i;
            if (!child.parentId) child.parentId = parent.id || '0';
            normalize(child);
        }
    }
}

normalize(data);

看起来应该可以工作。我测试了一下,但好像无法设置父ID。这是它的集成方式:http://jsfiddle.net/EJGHX/38/ 在第213行,如果您添加一个新的子项并将其移动,您将在控制台中看到结果。 - Stephen
@Stephen - 我已经快速查看了您提供的示例代码,似乎没有任何节点与ID相关联。您希望在哪里设置这些信息?目前,每个child.parentId都被设置为“0”,因为parent.id不存在。 - Andrew

3
递归是在同一个函数内部调用函数。您的示例根本不是递归;
function runRecursive(input) {
    for (var i = 0, l = input.length; i < l; i++) {
        var current = input[i];

        parentid = current.id == null ? '0' : current.id;
        current.index = i;
        if (current.children && current.children.length > 0) {
            runRecursive(current.children);
        };
    };
};

runRecursive(data.children);

此外,你应该使用 var 关键字来定义 i 和 l,否则它们将位于 window 上下文中,递归逻辑将被破坏。 虽然我不明白 parentid 变量是用来干什么的,以及为什么要在可见代码之外定义它。

Tommi,感谢您的回复。如果您看一下Andrew的答案,他的答案更接近我所寻找的,我正在从父对象的ID定义父ID。 - Stephen
确实。不要忘记为未来的用户标记安德鲁的答案。 - Tommi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接