使用 jQuery 操作 DOM 后模型和 ui 不同步 - knockout.js

Posted

技术标签:

【中文标题】使用 jQuery 操作 DOM 后模型和 ui 不同步 - knockout.js【英文标题】:model and ui out of sync after manipulating DOM with jQuery - knockout.js 【发布时间】:2021-10-07 13:15:10 【问题描述】:

我有以下 3 个复选框,一次只能选择一个:

<div class="radio-rows-wrapper" style="padding-top: 10px">
   <input type="checkbox" id="noMandateOption" name="mandate-option-selection" data-bind="checked: NoMandate"/></td>
   <label for="no-mandate">No Mandate</label><br>

   <input type="checkbox" id="electronicMandateOption" name="mandate-option-selection" data-bind="checked: ElectronicMandate" /></td>
   <label for="electronic-mandate">Electronic Mandate</label><br>

   <input type="checkbox" id="uploadMandateOption" name="mandate-option-selection" data-bind="checked: UploadMandate" /></td>
   <label for="upload-mandate">Upload Mandate</label>
</div>

我还有 3 个部分应该根据选中的复选框显示或隐藏:

<div data-bind="if: NoMandate"></div
<div data-bind="if: ElectronicMandate"></div
<div data-bind="if: UploadMandate"></div

以及用于更新复选框的以下 jQuery:

  $('input[type="checkbox"]').on('change', function () 
            $('input[name="' + this.name + '"]').not(this).prop('checked', false)
        );

When a checkbox is selected the correct section displays but after selecting another checkbox the section doesn't get hidden which makes me believe that somewhere the UI get's out of sync and that the values are not updated correctly.

【问题讨论】:

您的问题在这里有答案:***.com/questions/43027852/…。 【参考方案1】:

使用 jQuery 设置复选框的值可能不会触发导致 Knockout observable 值更新的事件。

如果您使用的是 Knockout,那么您真的不需要 jQuery 机制来取消选择其他复选框。我可以想到另外两种方法来实现这一点。

    最简单的解决方案是使用单选按钮。这就是单选按钮的意义 - 提供一个只能选择一个的选项。 为每个 observables 添加一个 .subscribe(function(val) ... ) 方法,并使用它来将其他的设置为 false

第二个想法看起来像......

var self = this;

self.ElectronicMandate = ko.observable();
self.ElectronicMandate.subscribe(function(val) 
    deselectOthers(val, self.NoMandate, self.UploadMandate);
);

self.NoMandate = ko.observable();
self.NoMandate.subscribe(function(val) 
    deselectOthers(val, self.ElectronicMandate, self.UploadMandate);
);

self.UploadMandate = ko.observable();
self.UploadMandate.subscribe(function(val) 
    deselectOthers(val, self.ElectronicMandate, self.NoMandate);
);

var deselectOthers = function(wasSelected) 
    if (!wasSelected) 
        // We're only interested if someone selected a checkbox.
        return;
    
    // Loop through each of the non-wasSelected arguments.
    // - These are the observables which we wish to set to false.
    for (var i = 1; i < arguments.length; i++) 
        arguments[i](false); // This is where the other observable is deselected.
    
;

.subscribe 方法描述为here。

【讨论】:

以上是关于使用 jQuery 操作 DOM 后模型和 ui 不同步 - knockout.js的主要内容,如果未能解决你的问题,请参考以下文章

为啥在我将不相关的 div 添加到 DOM 后,JQuery UI Datepicker 停止工作?

MVVM

使用 JQuery ajax 在 DOM 操作后附加事件

jQuery 捕获

Jquery基础之DOM操作

Jquery基础之DOM操作