通过javascript更改值时元素不更新错误状态
Posted
技术标签:
【中文标题】通过javascript更改值时元素不更新错误状态【英文标题】:Element not updating error state when value changed via javascript 【发布时间】:2017-10-31 03:34:30 【问题描述】:我有一个页面,其中包含一些淘汰赛,我正在尝试在其中实施验证。我有一个输入,允许用户通过这样的下拉菜单进行更改:
<div class="col-md-6 form-group has-feedback" data-bind="css: 'has-error': Term.hasError ">
<label for="ddlTerm" class="col-form-label" style="padding: 0;">Term</label>
<div class="input-group input-group-sm">
<input type="text" data-bind="textInput: Term" class="form-control input-sm" id="tbTerm" />
<div class="input-group-btn">
<button type="button" class="btn btn-warning dropdown-toggle" data-toggle="dropdown">Select <span class="caret"></span></button>
<ul class="dropdown-menu pull-right">
<li><a href="javascript:set_Term(12)">12 Months</a></li>
<li><a href="javascript:set_Term(24)">24 Months</a></li>
<li><a href="javascript:set_Term(36)">36 Months</a></li>
<li><a href="javascript:set_Term(48)">48 Months</a></li>
<li><a href="javascript:set_Term(60)">60 Months</a></li>
<li><a href="javascript:set_Term(72)">72 Months</a></li>
<li><a href="javascript:set_Term(84)">84 Months</a></li>
</ul>
</div>
</div>
<span data-bind='visible: Term.hasError, text: Term.validationMessage' class="help-block"></span>
</div>
还有JavaScript函数:
function set_Term(months)
var termInput = document.getElementById("tbTerm");
termInput.value = months;
;
值绑定到:
self.Term = ko.observable('').extend( required: 'Term is required' );
当值改变时,observable 会更新,但错误状态保持不变,输入保持红色,反馈保持可见。有没有办法强制输入意识到它的值已经改变并且应该清除错误?
我试图给元素focus()
,但这不起作用。
我发现的唯一一件事是提供包含 div 和验证消息 id,然后在 JS 函数中执行此操作:
$('#tbTermDiv').removeClass('has-error');
$('#tbTermNote').addClass('hidden');
这在视觉上起到了作用 - 错误消息消失了,文本框失去了红色,但如果用户再次清空该框,红色又回来了,但消息保持隐藏......所以不是最好的解决方案。
我对任何一种解决方案都很满意:淘汰赛、jQuery、纯 JS。
编辑:我注意到这不会更新 observable,所以当我通过 value 属性更改输入时,它不会更新 observable。
【问题讨论】:
是什么导致您的验证出现?您目前使用什么验证库? @JasonSpake 我正在使用此处找到的示例:knockoutjs.com/documentation/extenders.html @JasonSpake 我还安装了 Eric Barnard 的 knockout.validation v2.0.3,但我不确定我的设置是否使用它。 我看不出你所拥有的有什么问题。我使用您的代码和淘汰赛样本中的“必需”扩展程序进行了快速复制。它似乎工作正常? jsfiddle.net/jlspake/8ob0gj6q 是否只有在使用 set_term 函数之一后才会出现问题? 哦,这里还有更多内容。这是一个引导下拉菜单吗? 【参考方案1】:扩展器的工作方式与一般工程中的淘汰赛相同。它只知道对视图模型上的可观察对象所做的更改。使用 jquery 更新 UI 上控件的值不会更新底层视图模型,因此任何依赖的剔除代码都不知道要更新。
您可以将 set_term 函数更改为视图模型上的函数,并让它更新底层的 observable 而不是控件。然后使用数据绑定来调用函数而不是原始js。
self.set_Term = function(months)
self.Term(months);
;
...
<li><a data-bind="click: function()set_Term(84)">84 Months</a></li>
这是一个更新的示例:https://jsfiddle.net/jlspake/8ob0gj6q/3/
【讨论】:
我曾考虑过这种方式,但由于它已经设置好了,所以我想找出一种方法来做到这一点。我找到了一种简单的方法,我只是将$('#tbTerm').trigger('change');
添加到“set_term”函数中,现在它知道输入已更改,因此它更新了 observable 并清除了错误。谢谢您的帮助。这个答案是完全可以接受的,但我现在要使用 jQuery。以上是关于通过javascript更改值时元素不更新错误状态的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript | ReactJS:父状态更改不触发子道具更新