我有使用'bootstraptoggle'插件放在一起的复选框。我正在基于选中的框构建mongoDB查询。

该代码可以正常工作,但是我讨厌重复.change,有什么方法可以使这个DRY吗?

我有以下代码

的HTML

<div id="checkBoxContainer" class="container">
     <label class="checkbox-inline">
          <input type="checkbox" id="optionOne" data-onstyle="success" data- offstyle="danger" data-toggle="toggle">
     </label>
     <label class="checkbox-inline">
          <input type="checkbox" id="optionTwo" data-onstyle="success" data- offstyle="danger" data-toggle="toggle">
     </label>
</div>


JS

$('#optionOne').change(function() {
    if ($(this).prop('checked') == true) {
        queryBuilder.push($(this).attr("id"));
    } else if ($(this).prop('checked') == false) {
        queryBuilder.splice($(this).attr("id"));
    }
    console.log(queryBuilder);
});


$('#optionTwo').change(function() {
    if ($(this).prop('checked') == true) {
        queryBuilder.push($(this).attr("id"));
    } else if ($(this).prop('checked') == false) {
        queryBuilder.splice($(this).attr("id"));
    }
    console.log(queryBuilder);
});


我已经搜索并尝试了以下方法,但是没有运气。

$('document').on('change','#checkBoxContainer', function() {
      if ($(this).prop('checked') == true) {
        queryBuilder.push($(this).attr("id"));
    } else if ($(this).prop('checked') == false) {
        queryBuilder.splice($(this).attr("id"));
    }
    console.log(queryBuilder);

});

最佳答案

有什么办法可以使它干吗?


$('#optionOne, #optionTwo').change(...);


这称为selector group。变更处理程序中的代码都没有特定于它所挂钩的元素,因此纯粹是将其挂钩到两个元素的问题。



无关,但是:此行可疑:

queryBuilder.splice($(this).attr("id"));


splice至少需要两个参数:从处开始执行操作的索引,以及在该位置要删除的元素数量(如果要使用更多参数指定要插入的内容,则该值为0)。

如果您的目标是从数组中删除$(this).attr("id")的值,则不会这样做。代替:

var index = queryBuilder.indexOf($(this).attr("id"));
if (index != -1) {
    queryBuilder.splice(index, 1);
}


它将找到它,然后将其删除。



边注:

斜眼看,$(this).attr("id")只是写this.id的很长的路,而$(this).prop("checked")只是写this.checked的很长的路。 :-)

在进行比较时也没有任何理由要写== true(很少有理由要写=== true)。

最后,由于checked只能为true或false,因此不需要第二个if

所以:

$('#optionOne, #optionTwo').change(function() {
    var index;
    if (this.checked) {
        queryBuilder.push(this.id);
    } else {
        index = queryBuilder.indexOf(this.id);
        if (index != -1) {
            queryBuilder.splice(index, 1);
        }
    }
    console.log(queryBuilder);
});


或稍短:

$('#optionOne, #optionTwo').change(function() {
    var index;
    if (this.checked) {
        queryBuilder.push(this.id);
    } else if ((index = queryBuilder.indexOf(this.id)) != -1) {
        queryBuilder.splice(index, 1);
    }
    console.log(queryBuilder);
});




明显地过度分析它,我会注意到,如果我们认为未选中该复选框时有可能将其放置在数组中,则应该采取一些防御措施以避免将其放入两次:

$('#optionOne, #optionTwo').change(function() {
    var index = queryBuilder.indexOf(this.id);
    if (this.checked && index == -1) {
        queryBuilder.push(this.id);
    } else if (!this.checked && index != -1) {
        queryBuilder.splice(index, 1);
    }
    console.log(queryBuilder);
});


好吧,我现在停止。 :-)



Gah,还有一件事:一些非常老的浏览器没有Array#indexOf,因此,如果需要支持它们,则需要添加垫片或使用jQuery严重错误的$.inArray。要使用inArray,请将queryBuilder.indexOf(this.id)更改为$.inArray(queryBuilder, this.id)(无需更改其他任何内容)。

09-27 03:50
查看更多