如何确保在 bootstrap 更改无线电输入 'checked' 状态后实例化 FormData

How to ensure FormData is instantiated AFTER bootstrap has changed a radio input 'checked' status

我正在尝试通过 XMLHttpRequest 发送一些 FormData,当在 <label> 上检测到 click 事件时 <input type="radio" name="myName" id="myRadio" value="myValue">

let labels = [].slice.call(document.getElementsByClassName("myLabels"));
labels.forEach( (label) => {
    label.addEventListener("click", () => {
        //toggle label class to change css, then...
        let formData = new FormData(document.getElementById("myForm"));
        //ajax stuff now...

The fiddle.

问题是我已经实例化了 new FormData 在 bootstrap 的 js 开始设置 #myRadio.checked 之前点击标签,所以 FormDatamyName 值错误(它的值是先前活动标签的基础无线电输入的值,而不是当前活动标签的输入)。

如果不记录某种状态,就不可能检测到 #myRadio.checked 中的变化 - checked 状态是通过单击 bootstrap 中的标签设置的,因此实际 DOM checked="true" 属性未设置。

通过在此处引入超时来解决这个问题似乎是一种 hack。如何在 FormData 中获取正确的数据?

作为参考,here's the bootstrap docs 在样式为按钮的收音机上。我没有看到任何内置方法来判断方法何时完成。

[编辑] 更新代码(现在使用 jQuery 来简化事情) 和 the Fiddle you requested

$('label.btn').on('click', function() {
  console.log($(this).children('input').val());
  // first uncheck them all
  $('label.btn input').prop('checked', false)
    // notice how classes are in the parent of the input
    .parent().addClass('btn-secondary').removeClass('btn-primary').removeClass('active');
  // then check our child
  $(this).children('input').prop('checked', true)
    // notice how classes are in the parent of the input
    .parent().addClass('btn-primary active').removeClass('btn-secondary');
  // then the FormData
  let formData = new FormData(document.getElementById("myForm"));
  for (let pair of formData.entries()) {
    console.log(pair);
  }
});

/*
$('label.btn').on('click', function() {
  // click on the label is not the same as click on the input
  console.log($('input[name="preview"]:checked').val() + " is checked" );
});
*/
<head>
<!-- 
Bootstrap dependencies:
https://v4-alpha.getbootstrap.com/getting-started/introduction/#quick-start
-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js" integrity="sha384-3ceskX3iaEnIogmQchP8opvBy3Mi7Ce34nWjpBIwVTHfGYWQS9jwHDVRnpKKHJg7" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.3.7/js/tether.min.js" integrity="sha384-XTs3FgkjiBgo8qjEjBk0tGmf3wPrWtA6coPfQDfFEY8AnYJwjalXCiosYRBIBZX8" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/js/bootstrap.min.js" integrity="sha384-BLiI7JTZm+JWlgKa0M0kGRpJbF2J8q+qreVrKBC47e3K6BW78kGLrCkeRX6I9RoK" crossorigin="anonymous"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" rel="stylesheet"/>
</head>

<body>

<form id="myForm">
<div class="btn-group" data-toggle="buttons">
  <label class="btn btn-sm btn-primary active">
    <input type="radio" name="preview" id="preview-enabled" value="Alice" autocomplete="off" checked>Alice
  </label>
  <label class="btn btn-sm btn-secondary">
    <input type="radio" name="preview" id="preview-disabled" value="Bob" autocomplete="off">Bob
  </label>
</div>
</form>

</body>

===

第一次回答尝试是:

在下面的示例中,您可以找到一些更正,但请注意,奇怪的行为是由于单击事件时的选中状态(直到事件结束才会改变) )

let nodes = document.querySelectorAll('input[name="preview"]');
console.log(nodes);

[].slice.call(nodes).forEach( (node) => {
    node.parentNode.addEventListener("click", () => {
        console.log(node);
        console.log(node.parentNode.className);
        console.log(jQuery('input[name="preview"]:checked').val()) + ' is checked';
        if(node.checked === true){
            node.parentNode.className = node.parentNode.className.replace('btn-secondary', 'btn-primary' );
        } else {
            node.parentNode.className = node.parentNode.className.replace('btn-primary', 'btn-secondary' );
        }
        let formData = new FormData(document.getElementById("myForm"));
        for (let pair of formData.entries()) {
            console.log(pair);
        }
    }); //end eventListener function
});