由于一直在快速的迭代重构,为尽快实现预想的功能,代码有些凌乱,且没有注释……。但已经过较为全面的测试,可用性方面是没有问题的。后续会集中精力优化代码架构和性能。
以下是代码全貌,其中moduleDataFinder为功能入口函数,传入原始数据和数据筛选器对象,返回筛选结果数据。代码判断Array类型时,使用了jQuery的部分特性,可以进行简单的修改排除对jQuery的依赖。
function filterArrayData (data, key, value) { var proceedData = []; for (var i = 0; i < data.length; i++) { if ($.isArray(data[i])) { var newArr = []; for (var j = 0; j < data[i].length; j++) { newArr = filterArrayData(data[i], key, value); } proceedData.push(newArr); } else { if (data[i].hasOwnProperty(key)) { if (data[i][key] == value) { proceedData.push(data[i]); } } } } return proceedData; }; function sortArrayData (data, key) { var proceedData; var desc = false; var sortKey = key; if (key.substr(0, 1) === '!') { sortKey = key.substr(1); desc = true; } proceedData = data.slice(0); proceedData.sort(function (a, b) { if (sortKey.length) return (a[sortKey] < b[sortKey]) ^ desc ? -1 : 1; else return (a < b) ^ desc ? -1 : 1; }); return proceedData; }; var isArray = Array.isArray || function (obj) { return jQuery.type(obj) === "array"; }; function moduleDataFinder (data, bindFinder) { var proceedData = null; if (isArray(bindFinder)) { var newFinder = []; var arrProcess = []; for (var i = 0; i < bindFinder.length; i++) { if (typeof(bindFinder[i]) === "string") { newFinder.push(bindFinder[i]); } else if (isArray(bindFinder[i])) { arrProcess = bindFinder[i]; } else if (typeof(bindFinder[i]) === "object") { newFinder.push(bindFinder[i]); } } proceedData = data; if (isArray(proceedData) && arrProcess.length > 0) { for (i = 0; i < arrProcess.length; i++) { var arrFinder = arrProcess[i]; var key = ""; for (key in arrFinder)break; if (key === "$range") { if (typeof(arrFinder[key]) === "number") { proceedData = proceedData[arrFinder[key]]; } else if (isArray(arrFinder[key])) { proceedData = proceedData.slice(arrFinder[key][0], arrFinder[key][0] + arrFinder[key][1]); } } else if (key === "$filter") { for (var filterKey in arrFinder[key]) { if (!arrFinder[key].hasOwnProperty(filterKey))continue; proceedData = filterArrayData(proceedData, filterKey, arrFinder[key][filterKey]); } } else if (key === "$sort") { if (typeof(arrFinder[key]) === "string") { proceedData = sortArrayData(proceedData, arrFinder[key]); } else { for (var j = arrFinder[key].length - 1; j >= 0; j--) { proceedData = sortArrayData(proceedData, arrFinder[key][j]); } } } } } if (newFinder.length > 0) { if (isArray(proceedData)) { var tmpArr = []; for (i = 0; i < proceedData.length; i++) { var arrProceedData = {}; arrProceedData = moduleDataFinder(proceedData[i], newFinder).data; tmpArr.push(arrProceedData); } if (tmpArr.length > 0) { proceedData = tmpArr; } } else if (proceedData != null) { var tmpProceedData = null; for (i = 0; i < newFinder.length; i++) { var tmpData = moduleDataFinder(proceedData, newFinder[i]).data; if (tmpData == null) { tmpData = ""; } if (tmpProceedData == null) tmpProceedData = {}; if (typeof(newFinder[i]) === "string") { tmpProceedData[newFinder[i]] = tmpData; } else { var tmpKey = null; for (tmpKey in newFinder[i]) { break; } if (tmpKey === "$map") { for (tmpKey in tmpData) { break; } tmpData = tmpData[tmpKey]; } tmpProceedData[tmpKey] = tmpData; } } proceedData = tmpProceedData; } } } else if (typeof(bindFinder) === "object") { for (key in bindFinder) { if (!bindFinder.hasOwnProperty(key))continue; if (key.substr(0, 1) === '$') { if (key === "$hidden") { tmpData = moduleDataFinder(data, bindFinder[key]).data; if (tmpData != null) { proceedData = tmpData; } } else if (key === "$image") { tmpData = moduleDataFinder(data, bindFinder[key]).data; if (tmpData != null) { proceedData = tmpData; } } else if (key === "$html") { tmpData = moduleDataFinder(data, bindFinder[key]).data; if (tmpData != null) { proceedData = tmpData; } } else if (key === "$map") { var tmpMap = bindFinder[key]; for (var mapKey in tmpMap) { if (!tmpMap.hasOwnProperty(mapKey))continue; tmpData = moduleDataFinder(data, mapKey).data; var keyData = tmpData; var mapper = moduleMap[tmpMap[mapKey]]; if (typeof(mapper) === "function") { tmpData = mapper(keyData); } else { if (tmpData == null) { keyData = "$null"; } if (!moduleMap[tmpMap[mapKey]].hasOwnProperty(keyData)) { keyData = "$default"; } tmpData = moduleMap[tmpMap[mapKey]][keyData]; } proceedData = {}; proceedData[mapKey] = tmpData; break; } } else if (key === "$addition") { var tmpAdd = bindFinder[key]; proceedData = {}; for (i = 0; i < tmpAdd.length; i++) { proceedData[tmpAdd[i]] = moduleDataFinder(data, tmpAdd[i]).data; } } } else if (isArray(bindFinder[key])) { if (isArray(data)) { tmpArr = []; for (i = 0; i < data.length; i++) { arrProceedData = {}; arrProceedData = moduleDataFinder(data[i], bindFinder).data; tmpArr.push(arrProceedData); } if (tmpArr.length > 0) proceedData = tmpArr; } else if (data != null) { if (data.hasOwnProperty(key)) { tmpData = moduleDataFinder(data[key], bindFinder[key]); if (tmpData.data != null) { if (proceedData === null) proceedData = {}; proceedData = tmpData.data; } } } } else if (typeof(bindFinder[key]) === "string") { proceedData = moduleDataFinder(data[key], bindFinder[key]).data; } break; } } else if (typeof(bindFinder) === "string") { if (isArray(data)) { tmpArr = []; for (i = 0; i < data.length; i++) { arrProceedData = {}; arrProceedData = moduleDataFinder(data[i], bindFinder).data; tmpArr.push(arrProceedData); } if (tmpArr.length > 0) proceedData = tmpArr; } else if (data != null) { if (data.hasOwnProperty(bindFinder)) { proceedData = data[bindFinder]; } } } return {"data": proceedData}; };
接下来会介绍与这个数据筛选器匹配的数据绑定器。
一个JavaScript数据筛选器(四)——实现代码
本文介绍了一个JavaScript数据筛选器的实现,尽管代码在快速迭代重构中显得有些凌乱,但已通过全面测试,确保功能可用。主要功能入口是moduleDataFinder函数,它接受原始数据和筛选器对象,返回过滤后的数据。代码中对Array类型的判断借鉴了jQuery的部分特性,可按需调整以消除对jQuery的依赖。

被折叠的 条评论
为什么被折叠?



