换种方式实现,问题竟如此简单!

    在写一个table的javascript插件, 开始使用的方法是将数据放入一个2纬数组里作参数传入插件,但发现使用这种方法后对于td中内容的格式化非常不利,尤其对于列存在变动的情况。

看看旧实现:

$.fn.table=function(titles, data, formatter, css) {
	formatter = formatter||function(data, row, col, val){return val+'';};
	var html=["<table celspace='0' celpadding='0' border='0' >"],odd="";
	html.push("<tr class='title'><th class='lineno' style='color:grey'>-</th>");
	$.each(titles, function(i, title){
		html.push('<th><div class="value">'+title+'</div></th>');
	});
	html.push("</tr>");
	$.each(data, function(i, row){
		odd=(odd==="")?" class='odd'":"";
		html.push("<tr"+odd+">");
		html.push('<td class="lineno"><div class="value">');
		html.push(i+1);
		html.push('</div></td>');
		$.each(row, function(j, elm){
			html.push('<td><div class="value">');
			html.push(formatter(data, i, j, elm));
			html.push('</div></td>');
		});
		html.push("</tr>");
	});
	html.push('<table>');
	var table = $(html.join('')).appendTo(this.empty());
	if(css) {
		table.addClass(css);
	}
	return this;
};

   

 旧的实现中,在formatter中格式化显示时,数据的获取变得非常混乱,都通过各种索引进行,可读性很差                  

//如果列是固定的,这时要第3列和第2列进行百分比后显示,那么formatter是这样:
function formatter(data, col, row, val) {
    return ((val / data[1] )* 100).toFixed(2) + '%';
}
//如果列是变动的,比如刚开始显示的是小李的支出,1列是时间,2列为收入,3列为支出, 
//总列数为3列,每人显示两列,这时又把小刚的数据加了进来,那么就变成这样了5列(时间不用重复显示):
function formatter(data, col, row, val) {
    var type = (col-1) % 2;//当前列对应的项;
    if(type == 1) {//这是支出(减去了时间1列,下标比真实列数少1所以是1)
        var i = col-1;// 收入等于上一列,即col-1
        return ((val / data[i] )* 100).toFixed(2) + '%';
    } else {
        // ... ...
        return "";
    }
}

    看,这是不是非常之十分之超级麻烦 --!!!,更别说在此之前还要对data数组进行填充了。

再看看新的实现:

$.fn.table2 = function(col, row, titleGetter, dataGetter, css) {
	formatter = formatter||function(data, row, col, val){return val+'';};
	var html=["<table celspace='0' celpadding='0' border='0' >"],odd="";
	html.push("<tr class='title'><th class='lineno' style='color:grey'>-</th>");
	
	for (var i = 0; i < col; i++) {
		html.push('<th><div class="value">'+titleGetter(i)+'</div></th>');
	}
	html.push("</tr>");
	
	for (var r = 0; r < row; r++) {
		odd=(odd==="")?" class='odd'":"";
		html.push("<tr"+odd+">");
		html.push('<td class="lineno"><div class="value">');
		html.push(r+1);
		html.push('</div></td>');
		for (var c = 0; c < col; c++) {
			html.push('<td><div class="value">');
			html.push(dataGetter(c, r));
			html.push('</div></td>');
		}
		html.push("</tr>");
	}
	html.push('<table>');
	var table = $(html.join('')).appendTo(this.empty());
	if(css) {
		table.addClass(css);
	}
};

    新实现中,data已经不见踪影了, 数据获取仅通过行和列与回调函数进行,完全不用管数据格式,在dateGetter中数据的获取与格式化溶为一体,还可以方便的操纵原始对象,如:

var result = [
    [{ts: 0, shou:1000, zhi:20 },{ts: 1, shou:1000, zhi:25 }],//小李
    [{ts: 0, shou:1000, zhi:30 },{ts: 1, shou:1000, zhi:25 }],//小刚
]; 
//每个人显示的总列数还是2列,时间额外1列。
function dataGetter(col, row) {
    if(col == 0) {
        return result[ 0 ][ row ].ts;
    }
    var persionIdx = Math.ceil((col-1) / 2);//第几个人
    var persion = result[ persionIdx ];//对原始对象进行操作
    var type = (col-1) % 2;//收入or支出
    if(type == 0) {
        return persion.shou;//收入
    } else if(type == 1) {
        return ((persion.zhi / persion.shou)*100).toFixed(2) + '%';//支出
    }
}

兼容旧实现:

$.fn.table=function(titles, data, formatter, css) {
	if(!data[0]) {
		this.empty();
	} else {
		this.table2(data[0].length, data.length, function(col, row) {
			return titles[col];
		}, function(col, row) {
			return formatter(data, col, row, data[row][col]);
		});
	}
};


你可能感兴趣的:(JavaScript,jquery)