淘汰赛导致 JQuery 选择出现问题?验证不起作用

Posted

技术标签:

【中文标题】淘汰赛导致 JQuery 选择出现问题?验证不起作用【英文标题】:Knockout causing problems with JQuery select? Validation not working 【发布时间】:2020-04-24 06:51:12 【问题描述】:

所以我使用的是 Bootstrap、Jquery 2.2.3 和 Knockout 3.4.0。我遇到了一个非常奇怪的问题,无论我如何使用 JQuery 选择它,复选框总是会返回为 false 或 undefined。我认为这可能与 Knockout 数据绑定有关,但我不确定。

我在 ko.js 中使用自定义绑定来操作复选框并在选中该框时产生其他问题。

那么 rblBracedBolted 的验证应该取决于复选框是否被选中,但无论选中状态如何,所有值都会返回为“假”或“未定义”。

我知道当前的验证脚本没有意义,但我已经尝试了从 .prop 到 .attr 甚至 .is("checked") 等的所有内容。

<script type="text/javascript">

$(function () 
    ko.bindingHandlers.checkedProp = 
        init: function (element, valueAccessor) 
            Object.defineProperty(element, 'checked', 
                set: function (newValue) 
                    var value = valueAccessor();
                    value(newValue);
                
            );
        ,
        update: function (element, valueAccessor) 
            var value = ko.unwrap(valueAccessor());
            element.checked = value;
        
    ;
    ko.applyBindings(new viewModel());
);

$("#aspnetForm").validate(
    ignore: [],
    rules:  
    <%=rblBracedBolted.UniqueID %>: 
        required: 
            
                depends: function()
                
                    var sel = $('[id$=cblAddlCoverage1]').val();

                    if (sel == 'Earthquake')
                    
                        return true;
                    
                    else
                    
                        return false;
                    
                
            
    ,
  
);
</script>
.btn-default 
  text-shadow: 0 1px 0 #fff;
  background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
  background-image:      -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
  background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
  background-image:         linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
  background-repeat: repeat-x;
  border-color: #dbdbdb;
  border-color: #ccc;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>

<body>
<label class="btn btn-default">
<input type="checkbox" name="cblAddlCoverage1" id="cblAddlCoverage1" runat="server" value="Earthquake" data-toggle="button" data-bind="checkedProp: Earthquake" />
Earthquake
</label>

<div class="col-xs-12" data-bind="visible: Earthquake()==true">
    <div class="form-group">
        <label for="rblBracedBolted" class="control-label">Is the dwelling braced/bolted/tied down?</label>
        <div class="btn-group" data-toggle="buttons" style="padding-left: 10px">
            <label class="btn btn-default">
                <input type="radio" name="rblBracedBolted" id="rblBracedBolted" runat="server" value="Yes" />
                Yes
            </label>
            <label class="btn btn-default">
                <input type="radio" name="rblBracedBolted" runat="server" value="No" />
                No
            </label>
        </div>
    </div>
</div>

</body>

如果您需要更多信息,请随时提出任何问题。

【问题讨论】:

你没有包含你的viewModel,但是如果你想知道id为cblAddlCoverage1的元素是否被选中,使用$('#cblAddlCoverage1').is(":checked") viewModel 会提供更多答案吗?而且我已经尝试过 $('#cblAddlCoverage1').is(":checked") 无论是否选中复选框,它总是返回 false 。最初的 Javascript 函数 checkedProp 可能会导致这种情况吗? 我的回答是否帮助您解决了问题?如果是,请将其标记为已接受。如果没有,请告诉我,我会尽力提供进一步帮助。 【参考方案1】:

这段代码:

Object.defineProperty(element, 'checked', 
    set: function (newValue) 
        var value = valueAccessor();
        value(newValue);
    
);

在复选框元素上定义一个名为checked 的属性。这会覆盖元素的原版 checked 属性。但是,您永远不会设置此属性值,实际上,即使您会设置它would cause an infinite loop。 因此,尽管您可能认为 observable 的值是在复选框的每个 set 上设置的,但实际情况是从未调用过 set,因为 checked 属性已失效。

我建议你放弃自定义绑定,并使用 Knockout 的内置 checked binding(在下面的 sn-p 中,为了简洁,我删除了其他属性):

<input type="checkbox" id="cblAddlCoverage1" data-bind="checked: Earthquake" />

这是一个使用你的 html 的演示(javascript 是我的):

$(function () 
    var vm = function () 
      var self = this;
      self.Earthquake = ko.observable();
    
    ko.applyBindings(new vm());
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<body>
  <label class="btn btn-default">
    <input type="checkbox" name="cblAddlCoverage1" id="cblAddlCoverage1" runat="server" value="Earthquake" data-toggle="button" data-bind="checked: Earthquake" />
    Earthquake
  </label>
  <div class="col-xs-12" data-bind="visible: Earthquake()==true">
      <div class="form-group">
          <label for="rblBracedBolted" class="control-label">Is the dwelling braced/bolted/tied down?</label>
          <div class="btn-group" data-toggle="buttons" style="padding-left: 10px">
              <label class="btn btn-default">
                  <input type="radio" name="rblBracedBolted" id="rblBracedBolted" runat="server" value="Yes" />
                  Yes
              </label>
              <label class="btn btn-default">
                  <input type="radio" name="rblBracedBolted" runat="server" value="No" />
                  No
              </label>
          </div>
      </div>
  </div>
</body>

【讨论】:

我认为自定义绑定会导致问题,但我无法分解它在做什么。我不太喜欢JS。现在我遇到的问题是,当我使用引导程序 data-toggle="buttons" 时,选中的属性不会在点击时更新。想法? 我编辑了我的答案,现在它有完整的演示。您可以看到复选框运行良好,所以我不确定您面临什么问题。您是否按照建议更改了代码以使用data-bind="checked: Earthquake" @Cloz,你在这方面有什么进展吗? 不幸的是,没有,无线电输入似乎可以工作,所以在与业务确认后,我添加了另一个带有“无”值的按钮来切换两个值之间的输入,这完成了我需要的但仍然很奇怪海事组织。 问题已通过另一种方式解决,但您的代码 sn-p 使用工作模型完美地封装了问题,所以我绝对同意。抱歉,还在学习中,感谢您的关注!肯定还有其他事情发生,除了数据切换之外,我无法确定它可能来自哪里。可能与 CSS 有关,但就像我说的那样,它已经解决了,此时问题还没有实际意义。感谢您的所有帮助!

以上是关于淘汰赛导致 JQuery 选择出现问题?验证不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Select2 验证并强制用户选择至少 X 个项目

淘汰赛最小/最大验证不起作用

淘汰赛js jquery-mobile可折叠集不起作用

插入日期选择器后 Jquery 表单验证不起作用

如果选择框选项更改,则 JQuery 验证不起作用

使用 Jquery 验证插件提交 Ajax 表单不起作用