通过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更改值时元素不更新错误状态的主要内容,如果未能解决你的问题,请参考以下文章

在 React Form 中更新 props 更改的状态

JavaScript | ReactJS:父状态更改不触发子道具更新

未处理的异常:错误状态:尝试从 Hive 获取值时没有元素

更新 Map 的值时,“元素隐式具有 'any' 类型,因为类型的表达式不能用于索引类型”的错误

更改表值时Vuex Store不更新

如何在选择框更改JavaScript值时添加和删除消息?