如何在 ko.js 中跟踪多个复选框的状态变化

Posted

技术标签:

【中文标题】如何在 ko.js 中跟踪多个复选框的状态变化【英文标题】:How to track state change for multiple checkboxes in ko.js 【发布时间】:2020-12-23 17:49:27 【问题描述】:

这里是小提琴:https:https://jsfiddle.net/t5v7fmoq/1/

我想要达到的目标:

我希望能够根据收到的状态变量(可以有真值或假值)自动更新复选框视图

三个复选框的状态变量(带有初始状态)是:

  self.state1 = ko.observable(true);
  self.state2 = ko.observable(false);
  self.state3 = ko.observable(true);

在初始化函数中我填充 observablearray:

  self.init = function() 
    self.availableItems([
      new Item(1, "item1", self.state1(), self.onItemStateChange),
      new Item(2, "item2", self.state2(), self.onItemStateChange),
      new Item(3, "item3", self.state3(), self.onItemStateChange)
    ]);

在 Item 函数中,我设置了 observable 属性和 onChnage 方法:

function Item(id, name, state, onChange) 
  var self = this;

  self.id = ko.observable(id);
  self.name = ko.observable(name);
  self.state = ko.observable(state);

  self.state.subscribe(function(newValue) 
    onChange(self, newValue);
  );

使用 setTimeout 我伪造了一个一次性的 ajax 调用,它设置了新的状态:

setTimeout(()=>
self.state1(false)
self.state2(true)
self.state3(false)
self.availableItems()[0].state(self.state1())
self.availableItems()[1].state(self.state2())
self.availableItems()[2].state(self.state3())
,1000)

但是,我想要实现的是,我想避免输入以下内容:

self.availableItems()[0].state(self.state1())
self.availableItems()[1].state(self.state2())
self.availableItems()[2].state(self.state3())

我想使用常见做法和最佳编码来编写此行为并跟踪此状态... 我不知道如何以不同的方式解决这个问题。

我尝试使用这样的数组(以便稍后我可以使用 forach 和索引):

setTimeout(()=>
self.state1(false)
self.state2(true)
self.state3(false)
self.availableItems()[0].state(self.itemStatus()[0])
self.availableItems()[1].state(self.itemStatus()[1])
self.availableItems()[2].state(self.itemStatus()[2])
,1000)

但这并没有按预期工作。

简而言之,我想了解对行为进行编码的编码方法,以便在从服务器接收到新状态时,将正确的状态应用于正确的复选框,并正确更新正确的复选框视图。

【问题讨论】:

您的复选框值基于Item.state 显示。为什么需要ViewModel 中的state1state2itemStatus 属性?您始终可以使用 availableItems 访问它们,就像在 activeItemss 中所做的那样。 如何从服务器保存和获取数据?它基于id 字段? 因为 state1、state2 和 state3,我在真实代码中模拟一种情况,我从服务器接收数据,使用 ko.js mapp 插件映射 但是,为什么需要多个连续编号的状态属性?复选框状态在 Item 对象内。为什么需要ViewModel 中的重复信息。当发生变化时,您需要更新这两个地方。即使您从服务器获取数据,您也有id 参数来确定要更新哪个复选框? 这是因为我无法控制来自服务器端的内容。在这种情况下我将如何编码?你有什么建议? 【参考方案1】:

一般事实:如果您创建编号变量(item1item2item3),那么您做错了什么。使用数组。

根据如何您从服务器获取状态更新,updateState 的实现需要更改。我下面的实现假设你得到一个布尔值数组,例如[true, true, false].

让视图模型接受params 对象并用它初始化自己是个好主意,下面的代码就是这样做的。

function Item(params) 
    var self = this;

    self.id = ko.observable(params.id);
    self.name = ko.observable(params.name);
    self.state = ko.observable(params.state);


function ItemList(params) 
    var self = this;

    self.items = ko.observableArray(params.items.map(item => new Item(item)));

    self.updateState = function () 
        var items = self.items(),
            randomStates = items.map(item => Math.random() < 0.5);

        randomStates.forEach((state, i) => items[i].state(state));
    ;



var viewModel = new ItemList(
    items: [
        id: "item1", name: "Item 1", state: false,
        id: "item2", name: "Item 2", state: false,
        id: "item3", name: "Item 3", state: true,
    ]
);

ko.applyBindings(viewModel);
.switchName 
  font-weight: bold;

pre 
  position: absolute;
  right: 0;
  top: 0;
  left: 50%;
  font-size: smaller;
]
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<div data-bind="foreach: items">
  <div class="switchBox">
    <input type="checkbox" data-bind="checked: state, attr: id: id">
    <label class="switchName" data-bind="text: name, attr: for: id"></label>
  </div>
</div>
<button data-bind="click: updateState">Simulate Random Update</button>

<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

【讨论】:

非常感谢您的精彩解释。但是我无法将其标记为已回答,因为我仍然不知道如何解决此问题,因为您的假设是我从服务器返回数组,但它不是数组,我从返回 state1、state2 和 state3服务器。您能否解释一下如何针对这种情况修改此代码? @johndoe 如何你拿回来了?作为一个对象?它到底长什么样子? 这是准确的调用:BaseViewModel.call(this, "state1": 1, "state2": 1, "state3": 0, , baseEndpoint + '/status');在 BaseViewModel 我有这个: function BaseViewModel(defaults, remoteUrl, mappings) if (mappings === undefined) mappings = ; 变量自我 = 这个; self.remoteUrl = remoteUrl; // 可观察的属性 ko.mapping.fromJS(defaults, mappings, self); self.fetching = ko.observable(false); @johndoe 不要将代码发布到 cmets。将其添加到您的问题中,这样更容易阅读。 @johndoe ...当您使用它时,请像我在回答中所做的那样制作一个功能代码示例,其中包含 Knockout.js 和映射插件以及带有绑定的 html 视图,所以有一个“运行代码 sn-p”按钮来演示该问题。

以上是关于如何在 ko.js 中跟踪多个复选框的状态变化的主要内容,如果未能解决你的问题,请参考以下文章

ko.js学习一

跟踪 Corda 中的状态变化

如何管理状态并跟踪在 Angular 中填写的多个表单?

[在Java中检查多个复选框状态时如何防止重复的代码?

如何检查 Django 生成的多个复选框的状态?

UIButton 状态在滚动带有多个部分的 tableview 时发生变化 - Swift