我怎样才能使这个冗长的 jquery 变得优雅?
How can I elegantize this verbose jquery?
我需要获取选中的复选框的值(一次只允许选中一个),我有这段冗长的代码:
if (!checkboxSelected) {
return;
}
if($("#ckbx_produceusage").is(':checked')) {
rptval = $('#ckbx_produceusage').val();
}
else if($("#ckbx_deliveryperformance").is(':checked')) {
rptval = $('#ckbx_deliveryperformance').val();
}
else if($("#ckbx_fillrate").is(':checked')) {
rptval = $('#ckbx_fillrate').val();
}
else if($("#ckbx_pricecompliance").is(':checked')) {
rptval = $('#ckbx_pricecompliance').val();
}
setEmailAndGenerateValsForUnitReportPair(unitval, rptval);
有没有一种方法可以让这段代码不那么冗长又不会让人难以理解?我想动态地添加一个 class 到被选中的复选框,然后将其从任何以前添加了 class 的复选框中删除,然后根据当前装饰的 class 获取 rptval class。不过,这似乎有点臭或 Rubegoldbergesque,所以我正在寻找更好的解决方案。
更新
为 T.J。 Crowder,这里是HTML(Razor/ASP.NET MVC风格):
@foreach (var rpt in reports)
{
@* convert id to lowercase and no spaces *@
var morphedRptName = @rpt.report.Replace(" ", string.Empty).ToLower();
<input class="ckbx leftmargin8" id="ckbx_@(morphedRptName)" type="checkbox" value="@rpt.report" />@rpt.report
}
在不改变你的 HTML 的情况下,你至少可以通过使用循环来避免重复自己:
["#ckbx_produceusage", "#ckbx_deliveryperformance", "#ckbx_fillrate", "#ckbx_pricecompliance"].some(function(sel) {
var e = $(sel);
if (e.is(":checked")) {
rptval = e.val();
return true;
}
});
setEmailAndGenerateValsForUnitReportPair(unitval, rptval)
您可能会更改 HTML 以便初始数组可以是查询而不是 ID 选择器的硬编码列表。
您还需要考虑检查 none 的情况。永远不要假设某些东西是固定的。
function getValue(checkBoxes)
{
for ( var i = 0; i < checkBoxes.length; i++ )
{
var name = "#ckbx_" + checkBoxes[ i ];
if ( $( name ).is( "checked" ) ) return $( name ).val();
}
//None were checked
return null; //Should throw exception
}
rptval = getValue( [ "produceusage", "deliveryperformance", "fillrate", "pricecompliance" ] );
JQuery 集合是可过滤的,所以我建议使用以下内容:
// get value of first checked checkbox
var rptval = $(
"#ckbx_produceusage,"+
"#ckbx_deliveryperformance,"+
"#ckbx_fillrate,"+
"#ckbx_pricecompliance"
).filter(':checked').first().val();
注意:.first()
甚至可能是不必要的,因为 .val()
获取集合中第一个元素的值。为了便于阅读而保留。
尝试使用 .each()
$("input[type='checkbox']").each(function() {
var rptval = 0;
if ($(this).is(":checked")) {
rptval = 1;
}
setEmailAndGenerateValsForUnitReportPair(unitval, rptval);
});
$(function()
{
...
// IF (these are the only elements that id starts with ckbx_) THEN
rptval = $('[id^=ckbx_]').filter(':checked').val();
// ELSE
// this syntax is more maintainable than $('#ckbx_produceusage, #ckbx_fillrate, ... selectors à la queue');
rptval = $('#ckbx_produceusage').add('#ckbx_fillrate').add('#ckbx_deliveryperformance').add('#ckbx_pricecompliance').filter(':checked').val();
// FI
...
});
我需要获取选中的复选框的值(一次只允许选中一个),我有这段冗长的代码:
if (!checkboxSelected) {
return;
}
if($("#ckbx_produceusage").is(':checked')) {
rptval = $('#ckbx_produceusage').val();
}
else if($("#ckbx_deliveryperformance").is(':checked')) {
rptval = $('#ckbx_deliveryperformance').val();
}
else if($("#ckbx_fillrate").is(':checked')) {
rptval = $('#ckbx_fillrate').val();
}
else if($("#ckbx_pricecompliance").is(':checked')) {
rptval = $('#ckbx_pricecompliance').val();
}
setEmailAndGenerateValsForUnitReportPair(unitval, rptval);
有没有一种方法可以让这段代码不那么冗长又不会让人难以理解?我想动态地添加一个 class 到被选中的复选框,然后将其从任何以前添加了 class 的复选框中删除,然后根据当前装饰的 class 获取 rptval class。不过,这似乎有点臭或 Rubegoldbergesque,所以我正在寻找更好的解决方案。
更新
为 T.J。 Crowder,这里是HTML(Razor/ASP.NET MVC风格):
@foreach (var rpt in reports)
{
@* convert id to lowercase and no spaces *@
var morphedRptName = @rpt.report.Replace(" ", string.Empty).ToLower();
<input class="ckbx leftmargin8" id="ckbx_@(morphedRptName)" type="checkbox" value="@rpt.report" />@rpt.report
}
在不改变你的 HTML 的情况下,你至少可以通过使用循环来避免重复自己:
["#ckbx_produceusage", "#ckbx_deliveryperformance", "#ckbx_fillrate", "#ckbx_pricecompliance"].some(function(sel) {
var e = $(sel);
if (e.is(":checked")) {
rptval = e.val();
return true;
}
});
setEmailAndGenerateValsForUnitReportPair(unitval, rptval)
您可能会更改 HTML 以便初始数组可以是查询而不是 ID 选择器的硬编码列表。
您还需要考虑检查 none 的情况。永远不要假设某些东西是固定的。
function getValue(checkBoxes)
{
for ( var i = 0; i < checkBoxes.length; i++ )
{
var name = "#ckbx_" + checkBoxes[ i ];
if ( $( name ).is( "checked" ) ) return $( name ).val();
}
//None were checked
return null; //Should throw exception
}
rptval = getValue( [ "produceusage", "deliveryperformance", "fillrate", "pricecompliance" ] );
JQuery 集合是可过滤的,所以我建议使用以下内容:
// get value of first checked checkbox
var rptval = $(
"#ckbx_produceusage,"+
"#ckbx_deliveryperformance,"+
"#ckbx_fillrate,"+
"#ckbx_pricecompliance"
).filter(':checked').first().val();
注意:.first()
甚至可能是不必要的,因为 .val()
获取集合中第一个元素的值。为了便于阅读而保留。
尝试使用 .each()
$("input[type='checkbox']").each(function() {
var rptval = 0;
if ($(this).is(":checked")) {
rptval = 1;
}
setEmailAndGenerateValsForUnitReportPair(unitval, rptval);
});
$(function()
{
...
// IF (these are the only elements that id starts with ckbx_) THEN
rptval = $('[id^=ckbx_]').filter(':checked').val();
// ELSE
// this syntax is more maintainable than $('#ckbx_produceusage, #ckbx_fillrate, ... selectors à la queue');
rptval = $('#ckbx_produceusage').add('#ckbx_fillrate').add('#ckbx_deliveryperformance').add('#ckbx_pricecompliance').filter(':checked').val();
// FI
...
});