我正在使用 Node.js 和 Dust.js 模板,这些模板通过 Mongoose 使用来自 MongoDB 的值填充分层列表。在数据到达模板之前尝试过滤数据显然是理想的,但我发现很少能帮助我弄清楚如何做到这一点,所以我在客户端通过 jQuery 进行。这段代码是一个严重的黑客,所以请原谅!但是,至少对于第一级合并,它是有效的。
我的 Mongoose 数据填充了按类别和子类别排列的卡片组的深入分层菜单(HTML 中的简单 ul li 类型列表结构)。并非每个牌组都有一个子类别,或相同数量的子类别。这些都嵌入在每个平台中,因为我在这里真正接受了 noSQL 的想法!但是来自 MySQL 的这绝对不是在 Mongoose 中那么容易安排的。
因此,当类别和子类别嵌入到每个卡片组的 JSON 中时,我需要合并所有类别,然后将子类别 1 一个一个地合并,这样卡片组就会进入适当的位置,以便快速导航到卡片组的数据。
我今天编写的代码(正如我所说的那样非常可怕!)将合并列表的顶层。运行此代码后,对于具有重复项的顶级类别,将它们合并,并保留所有子项。
我的问题:我想大大改进这段代码。现在我正在考虑为我的 4 或 5 个级别中的每一个创建一个这样的函数,这以一种我不想被限制的方式限制我(如果一个主题真的需要 6 个级别怎么办?)具体来说,我我喜欢:
一种合并列表部分的方法,包括子项,递归地查看下一级是否有重复的主题。
从底层开始合并是否明智?
正如我所说,在渲染模板之前过滤数据可能会更好,但我还没有尝试过考虑这一点。
这是我的代码:
function mergeLevel1() {
var count = 0;
var subcatText;
var subcatTextCurrent;
$.each($("ul.rootlist > li").not("ul li ul a"), function() {
var firstNode = $(this)
var nodeText = $("a:first", this).text();
//toastr.warning('nodeText is ' + nodeText)
$.each($("ul.rootlist > li").not("ul li ul a").not(firstNode), function() {
var siblingNode = $(this)
var siblingText = $("a:first", this).text();
//toastr.info('running sibling, siblingText is ' + siblingText)
if (nodeText == siblingText) {
toastr.info('i found a duplicate for ' + siblingText)
siblingNode.children().find('li').each(function(){
if (count == 0) {
subcatText = $(this).text();
}
subcatTextCurrent = $(this).text();
count++
toastr.warning("found children of a duplicate " + $(this).text())
//var targetNode = $("a:first", theNode).text()
toastr.info('try appending to ' + '#'+siblingText+'_ul'+'_'+subcatText)
if (count > 1) {
toastr.error('moving node!')
$(this).appendTo('#'+siblingText+'_ul_'+subcatText);
}
})
}
});
removeEmpties();
});
// end merge level 1
}
function removeEmpties() {
$('ul:empty').parent().remove();
}