如何在 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
中的state1
、state2
和itemStatus
属性?您始终可以使用 availableItems
访问它们,就像在 activeItemss
中所做的那样。
如何从服务器保存和获取数据?它基于id
字段?
因为 state1、state2 和 state3,我在真实代码中模拟一种情况,我从服务器接收数据,使用 ko.js mapp 插件映射
但是,为什么需要多个连续编号的状态属性?复选框状态在 Item
对象内。为什么需要ViewModel
中的重复信息。当发生变化时,您需要更新这两个地方。即使您从服务器获取数据,您也有id
参数来确定要更新哪个复选框?
这是因为我无法控制来自服务器端的内容。在这种情况下我将如何编码?你有什么建议?
【参考方案1】:
一般事实:如果您创建编号变量(item1
、item2
、item3
),那么您做错了什么。使用数组。
根据如何您从服务器获取状态更新,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 中跟踪多个复选框的状态变化的主要内容,如果未能解决你的问题,请参考以下文章