gpt4 book ai didi

knockout.js - knockout : Complex binding with observable arrays and checkboxes

转载 作者:行者123 更新时间:2023-12-04 03:05:41 25 4
gpt4 key购买 nike

我有一系列可观察到的服务,这些服务可能由一家公司提供(即销售、服务、咨询)。这些服务中的每一项都可能由该公司在零个或多个美国州执行,并且每个州都有一个可选的认证编号。因此,服务有一个可观察的位置数组,位置是状态和证书编号的组合。

function Service(name) {
var self = this;

self.Name = ko.observable(name);
self.Locations = ko.observableArray();
}

function Location(state) {
var self = this;

self.State = ko.observable(state);
self.CertNum = ko.observable();
}

在用户界面中,我想显示美国所有州的单个列表。用户将勾选公司经营所在的每个州旁边的复选框,从而制作州的“主列表”。反过来,这个主列表会驱动出现在每个可能服务下的选择。

例如,用户在主列表中勾选“Alabama”和“Arizona”。然后,UI 为每个服务呈现一个单独的位置,作为复选框和文本框的组合。这是主视图模型:

function viewModel() {
var self = this;

self.AllStates = [
{ name: "Alabama", abbrev: "AL" },
{ name: "Alaska", abbrev: "AK" },
{ name: "Arizona", abbrev: "AZ" },
{ name: "Arkansas", abbrev: "AR" }
];

self.BusinessStates = ko.observableArray();

self.AllSelectedStates = ko.computed( function() {
return ko.utils.arrayFilter( self.AllStates, function(item) {
return self.BusinessStates.indexOf(item.abbrev) >= 0;
});
});

self.Services = ko.observableArray([
new Service("Sales"),
new Service("Service"),
new Service("Consulting")
]);
}

一个简单的 View 看起来像:

<h2>Master List</h2>
<ul data-bind="foreach: AllStates">
<li>
<label><input type="checkbox" data-bind="value: abbrev, checked: $root.BusinessStates"/> <span data-bind="text: name"></span></label></li>
</ul>

<h2>Services</h2>
<div class="service" data-bind="foreach: Services">
<h3 data-bind="text: Name"></h3>
<ul data-bind="foreach: $root.AllSelectedStates">
<li>
<label>
<input type="checkbox" data-bind="value: abbrev, checked: $parent.Locations" />
<span data-bind="text: name"></span>
</label>
<input type="text" placeholder="Cert. Number" data-bind="value: ??" />
</li>
</ul>
</div>

该 View 至少让我进入服务的 Locations 数组的状态,但我不知道如何绑定(bind) CertNum 属性。

假设用户在主列表中选择了阿拉巴马州和亚利桑那州。现在,对于“销售”服务,用户勾选“亚利桑那”并输入认证编号“98765”。在“咨询”服务下,用户勾选“阿拉巴马”并且不输入证书编号。理想情况下,我希望生成的 JSON 片段看起来像:

"Services": [
{
"Name": "Sales",
"Locations": [
{
"State": { "name": "Arizona", "abbrev": "AZ" },
"CertNum": "98765"
}
]
},
{
"Name": "Service",
"Locations": []
},
{
"Name": "Consulting",
"Locations": [
{
"State": { "name": "Alabama", "abbrev": "AL" },
"CertNum": null
}
]
}
]

我可以呈现和绑定(bind)美国各州的“主列表”。我可以遍历服务并呈现一个 UI,该 UI 为每个可用的服务位置提供控件(即状态的复选框,证书编号的文本框)。我无法绑定(bind)服务位置控件以控制适当 Locations 数组中位置的成员资格,并同时影响认证编号的值。

我所做的最接近的尝试是相当复杂和老套的,我使用的是 knockout-postBox plugin将 viewModel.AllSelectedStates 属性链接到每个服务模型上的类似属性,然后将新位置推送到每个 Service.Locations 数组中。它几乎 可以工作,除了它会在主列表中选中或取消选中某个状态时消除对服务的更改。此外,我必须将每个可用位置推送到每个服务的 Locations 数组中,并依靠位置上的 IsSelected bool 标志来确定它是否已被选中(我宁愿将位置只是放在被选中的数组)。

您可以在这个 JSFiddle 中看到尝试:http://jsfiddle.net/cbono/PU6Sq/23/

它的好处在于它展示了 UI 应该如何表现。但我认为如果没有 postBox 插件这是可能的,我只是没有以正确的方式看待问题来找出答案。我花了几天时间解决这个问题,但无法想出 100% 有效的解决方案。

最佳答案

使用 visible 绑定(bind)比管理集合事件更容易。

<li data-bind="visible: State().IsSelected">

http://jsfiddle.net/MizardX/XTkpb/


如果你真的需要处理它们,你可以在 Services 对象中缓存 StateAndCert 对象:

var self = this,
cache = {};

self.Locations = ko.computed(function () {
return ko.utils.arrayMap(states(), function (item) {
var key = item.Abbrev();
if (cache[key] === undefined) {
cache[key] = new StateAndCert(item);
}
return cache[key];
});
});

http://jsfiddle.net/MizardX/HMAtE/


要在 JSON 呈现中隐藏某些属性,您可以将它们填充到 function(){} 属性中:

self.Meta = function(){};
self.Meta.IsSelected = ko.observable(false);

关于knockout.js - knockout : Complex binding with observable arrays and checkboxes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13925909/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com