在for循环

时间:2018-02-16 17:00:54

标签: javascript jquery arrays loops for-loop

我有一组复选框,根据选择的项目,将显示不同的上传字段。为了实现这一点,我想动态创建一个包含我想要获取的所有类的数组(没有重复)。

我创建了一个包含详细信息的对象:

var uploadReq = {
    a: [".document-2"],
    b: [".document-1", ".document-3"],
    c: [".document-1"],
    d: [".document-2", ".document-3"],
    e: [],
    f: [".document-3"]
};

在这个例子中,如果有人选择了A类和B类,我们应该得到类似[".document-2", ".document-1", ".document-3"]的数组(顺序不重要)。

我有一个这样的事件监听器:

$("#client-cat").change(function() {
    var arr = $("#client-cat input");
    var classes = [];

    for(i=0; i<arr.length; i++) {
        if(arr[i].checked) {
            var value = arr[i].value;
            var arr2 = uploadReq[value];
            $.extend(classes, arr2);
        }
    };

    console.log(classes);
})

HTML:

<form>
    <div class="segment">
        <label for="client-cat">Client category:</label>
        <div id="client-cat">
            <div>
                <input type="checkbox" tabindex="0" name="client-cat" value="a">
                <label>Category A</label>
            </div>

            <div>
                <input type="checkbox" tabindex="0" name="client-cat" value="b">
                <label>Category B</label>
            </div>

            <div>
                <input type="checkbox" tabindex="0" name="client-cat" value="c">
                <label>Category C</label>
            </div>

            <div>
                <input type="checkbox" tabindex="0" name="client-cat" value="d">
                <label>Category D</label>
            </div>

            <div>
                <input type="checkbox" tabindex="0" name="client-cat" value="e">
                <label>Category E</label>
            </div>

            <div>
                <input type="checkbox" tabindex="0" name="client-cat" value="f">
                <label>Category F</label>
            </div>
        </div>
    </div>

    <div class="segment">
        <div class="document-1">
            <label for="document-1">Upload a copy of Document 1:</label>
            <input type="file" id="document-1" name="1" accept=".pdf">
        </div>

        <div class="document-2">
            <label for="document-2">Upload a copy of Document 2:</label>
            <input type="file" id="document-2" name="2" accept=".pdf">
        </div>

        <div class="document-3">
            <label for="document-3">Upload a copy of Document 3:</label>
            <input type="file" id="document-3" name="3" accept=".pdf">
        </div>
    </div>

</form>

但是,当我运行检查了类别A和类别B的代码时,我只获得[".document-1", ".document-3"]

我相信正在发生的事情是,每次for循环重新启动时,它都会恢复为classes的原始值,而不是从循环结束处获取值并重新启动它。

研究/尝试修复:

  • 查看this thread讨论使用$.extend解决类似问题(例如合并两个数组而不重复)
  • 通过尝试代码测试是否是一个范围问题:

    $("#client-cat").change(function() {
        var arr = $("#client-cat input");
        var classes = [];
    
        for(i=0; i<arr.length; i++) {
            if(arr[i].checked) {
                classes.push("bob");
            }
        }
    
        console.log(classes);
    })
    

    但是上面记录的数组的"bob"class一样多,所以我不认为这是push范围的问题。

  • 考虑其他组合数据的方法。示例:map有效,但我最终得到数组内的数组,这不是我想要的。示例:IEnumerable<int> xx = null; var tt = xx?.Where(x => x > 2).Select(x => x.ToString()); 可能会执行此操作,但不会清除重复项。

JSFiddle here.

2 个答案:

答案 0 :(得分:4)

$.extend不是追加数组的正确方法。它通过在第二个(或更高版本)对象中添加不在第一个对象中的属性来合并对象。但是当你使用数组时,两个数组都有0属性,所以第二个数组的第一个元素没有添加到第一个数组中。

附加数组的函数是concat。它不会修改数组,您需要分配回变量。

$("#client-cat").change(function() {
    var arr = $("#client-cat input:checked");
    var classes = [];

    arr.each(function() {
        classes = classes.concat(uploadReq[this.value]);
    });

    console.log(classes);
})

答案 1 :(得分:1)

jQuery.extend()

  

第一个参数:如果传入其他对象,则会接收新属性的对象,如果它是唯一参数,则会扩展jQuery命名空间。

因此,对于阵列,您将面临问题。

您可以使用以下方法: classes = [ ...classes, ...arr2]

&#13;
&#13;
var uploadReq = {
  a: [".document-2"],
  b: [".document-1", ".document-3"],
  c: [".document-1"],
  d: [".document-2", ".document-3"],
  e: [],
  f: [".document-3"]
};

$("#client-cat").change(function() {
  var classes = [];
  var arr = $("#client-cat input");
  for (var i = 0; i < arr.length; i++) {
    if (arr[i].checked) {
      var value = arr[i].value;
      var arr2 = uploadReq[value];
      classes = [ ...classes, ...arr2];
    }
  }

  console.log(classes);
});
&#13;
.segment {
  margin-bottom: 2em;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" type="text/css" href="checkbox-display.css">
</head>

<body>

  <form>
    <div class="segment">
      <label for="client-cat">Client category:</label>
      <div id="client-cat">
        <div>
          <input type="checkbox" tabindex="0" name="client-cat" value="a">
          <label>Category A</label>
        </div>

        <div>
          <input type="checkbox" tabindex="0" name="client-cat" value="b">
          <label>Category B</label>
        </div>

        <div>
          <input type="checkbox" tabindex="0" name="client-cat" value="c">
          <label>Category C</label>
        </div>

        <div>
          <input type="checkbox" tabindex="0" name="client-cat" value="d">
          <label>Category D</label>
        </div>

        <div>
          <input type="checkbox" tabindex="0" name="client-cat" value="e">
          <label>Category E</label>
        </div>

        <div>
          <input type="checkbox" tabindex="0" name="client-cat" value="f">
          <label>Category F</label>
        </div>
      </div>
    </div>

    <div class="segment">
      <div class="document-1">
        <label for="document-1">Upload a copy of Document 1:</label>
        <input type="file" id="document-1" name="1" accept=".pdf">
      </div>

      <div class="document-2">
        <label for="document-2">Upload a copy of Document 2:</label>
        <input type="file" id="document-2" name="2" accept=".pdf">
      </div>

      <div class="document-3">
        <label for="document-3">Upload a copy of Document 3:</label>
        <input type="file" id="document-3" name="3" accept=".pdf">
      </div>
    </div>

  </form>

  <script src="http://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous">
  </script>

</body>

</html>
&#13;
&#13;
&#13;