我如何压缩这些重复的代码并使其动态

How do I compress this duplicate code and make it dynamic?

本文关键字:代码 动态 何压缩 压缩      更新时间:2023-09-26

我有一些重复的代码添加下拉过滤器到我的数据表(使用jQuery数据表插件),看起来像这样:

// filter based on company type
$.fn.dataTable.ext.search.push(
    function( settings, data, dataIndex ) {
        selectedType = $('#companyType').val();
        if(selectedType.toLowerCase() === "all"){
            return true;    
        }
        if(selectedType.toLowerCase() === data[2].toLowerCase()){
            return true;                    
        }
        return false;
    }
);
// filter based on status type
$.fn.dataTable.ext.search.push(
    function( settings, data, dataIndex ) {
        selectedType = $('#status').val();
        if(selectedType.toLowerCase() === "all"){
            return true;    
        }
        if(selectedType.toLowerCase() === data[3].toLowerCase()){
            return true;                    
        }
        return false;
    }
);
// filter based on account type
$.fn.dataTable.ext.search.push(
    function( settings, data, dataIndex ) {
        selectedType = $('#accountType').val();
        if(selectedType.toLowerCase() === "all"){
            return true;    
        }
        if(selectedType.toLowerCase() === data[9].toLowerCase()){
            return true;                    
        }
        return false;
    }
);

可以看到,这些函数之间的唯一区别是(过滤器下拉列表的)elementID和列索引。我想分解出重复的代码,并使用循环或函数使其可重用。

我尝试在javascript中使用一个键值对象,然后循环为每个添加一个过滤器:

<!--- Create object that stores key-value pairs for all dropdown filters; key is column index, value is filter element ID --->
var dropDownFilters = { 2: "companyType", 3: "status", 9: "accountType" }
<!--- Loop through dropdown filters and set filter for each --->
for(var key in dropDownFilters){
    $.fn.dataTable.ext.search.push(
        function( settings, data, dataIndex ) {
            selectedType = $('#' + dropDownFilters[key]).val();
            if(selectedType.toLowerCase() === "all"){
                return true;    
            }
            if(selectedType.toLowerCase() === data[key].toLowerCase()){
                return true;                    
            }
            return false;
        }   
    );      
}

这不能正常工作,因为它只使用最后的值(9和accounttype)创建过滤器函数,所以第三个过滤器工作,而其他过滤器不起作用。

我可以完成我想通过服务器端coldfusion代码完成加载:

<cfset dropDownFilters = [  { colIndex=2, elementID = "companyType" }, 
                            { colIndex=3, elementID = "status"},
                            { colIndex=9, elementID = "accountType"} ] />
<cfloop from="1" to="#ArrayLen(dropDownFilters)#" index="i">
    $.fn.dataTable.ext.search.push(
        function( settings, data, dataIndex ) {
            selectedType = $('#<cfoutput>#dropDownFilters[i].elementID#</cfoutput>').val();
            if(selectedType.toLowerCase() === "all"){
                return true;    
            }
            if(selectedType.toLowerCase() === data[<cfoutput>#dropDownFilters[i].colIndex#</cfoutput>].toLowerCase()){
                return true;                    
            }
            return false;
        }   
    );
</cfloop>

然而,这感觉很笨拙。我更喜欢通过纯javascript来完成,没有理由使用ColdFusion。

我如何使用循环或函数重构这个重复的代码(哪一个更可取)?

您可以创建函数来重用一些代码。代码复制是程序设计中的一种反模式。

function prepare(selector, index)
{
    $.fn.dataTable.ext.search.push(
        function( settings, data, dataIndex ) {
            selectedType = $(selector).val();
            if(selectedType.toLowerCase() === "all"){
                return true;    
            }
            if(selectedType.toLowerCase() === data[index].toLowerCase()){
                return true;                    
            }
            return false;
        }
    );
}
然后你的代码看起来像:
prepare('#companyType', 2);
prepare('#status', 3);
prepare('#accountType', 9);