英文:
Knockout causing problems with JQuery select? Validation not working
问题
我正在使用Bootstrap、JQuery 2.2.3和Knockout 3.4.0。我遇到一个非常奇怪的问题,无论我如何使用JQuery选择它,复选框始终返回false或undefined。我认为这可能与Knockout的数据绑定有关,但我不确定。
我在ko.js中使用自定义绑定来操作复选框,并在选中复选框时生成其他问题。然后,rblBracedBolted的验证应该依赖于复选框是否选中,但无论选中状态如何,所有值都返回'false'或'undefined'。
我知道当前的验证脚本没有意义,但我已经尝试了从.prop到.attr甚至.is("checked")等等的所有方法。
$(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 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>
如有更多信息需求,请随时提问。
英文:
so I'm using Bootstrap, Jquery 2.2.3, and Knockout 3.4.0. I'm having a really odd issue where a checkbox will always come back as false or undefined no matter how I select it with JQuery. I think this may have something to do with the Knockout data-bind but I'm not certain.
I'm using a custom binding in ko.js in order to manipulate the checkboxes and have the other questions produce when the box is checked.
Then validation of the rblBracedBolted is supposed to be dependent on whether the checkbox is checked or not but all values come back as 'false,' or 'undefined,' regardless of checked status.
I know the current script for validation doesn't make sense but I've tried everything from .prop to .attr and even .is("checked") etc, etc.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
<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>
<!-- language: lang-css -->
.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;
}
<!-- language: lang-html -->
<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>
<!-- end snippet -->
Feel free to ask any questions if you need more info.
答案1
得分: 1
这段代码:
Object.defineProperty(element, 'checked', {
set: function (newValue) {
var value = valueAccessor();
value(newValue);
}
});
在复选框元素上定义了一个名为checked
的属性。这会覆盖元素的原生checked
属性。然而,您从未设置此属性的值,实际上,即使您这样做,它会导致无限循环。因此,尽管您可能认为每次复选框的set
事件都会设置可观察对象的值,但实际上从未调用set
,因为checked
属性已被无效化。
我建议您放弃自定义绑定,而是使用Knockout的内置checked
绑定(在以下代码片段中,我删除了其他属性以简化代码):
<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());
});
希望这能帮助您理解代码和建议。
英文:
This code:
Object.defineProperty(element, 'checked', {
set: function (newValue) {
var value = valueAccessor();
value(newValue);
}
});
defines a property named checked
on the checkbox element. This overwrites the vanilla checked
property of the element. However, you never set this property value, and actually, even if you would, it would cause an infinite loop.
Thus, although you may have thought that the value of the observable is set on each set
of the checkbox, what actually happens is that set
is never called, because the checked
property was invalidated.
I suggest you drop the custom binding, and use Knockout's built-in checked
binding (in the following snippet, I removed other attributes for brevity):
<input type="checkbox" id="cblAddlCoverage1" data-bind="checked: Earthquake" />
Here's a demonstration using your html (javascript is mine):
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
$(function () {
var vm = function () {
var self = this;
self.Earthquake = ko.observable();
}
ko.applyBindings(new vm());
});
<!-- language: lang-html -->
<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>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论