gpt4 book ai didi

foreach - Knockout JS foreach嵌套,所有字段的值更新

转载 作者:行者123 更新时间:2023-12-02 12:28:59 25 4
gpt4 key购买 nike

我正在使用knockout js来完成任务。我的模型是这样的:

var ServiceLevelRates = function(data, availableClasses) {
return {
TaxTypeID: ko.observable(data.Key),
TaxTypeName: ko.observable(data.Name),
ExtendedTaxTypeName: data.Name.replace(/\s+/g, ''),
ApplyAfter: ko.observable(-1),
TaxClasses: ko.observableArray(availableClasses)
};
};

var TaxClass = function(data, availableServices) {
return {
ServiceClassID: data.ServiceClassID,
ServiceClassName: ko.observable(data.ServiceClassName),
TaxServices: ko.observableArray(availableServices)
};
};

var TaxService = function(data) {
return {
ServiceID: ko.observable(data.ServiceID),
ServiceName: ko.observable(data.ServiceName),
ServiceRate: ko.observable(data.ServiceRate > 0 ? data.ServiceRate : "").extend({ numeric: 2 })
};
};

我的 html 是这样的:

<tbody  data-bind="foreach: ServiceLevelRates">
<tr>
<td style="width:100%;">
<table width="100%">
<tr>
<td style="width:2%;">
<img src="../../Images/del_up.gif" onclick="HideMyChilds(this);" />
</td>
<td data-bind="text: TaxTypeName">

</td>
</tr>
<tr>
<td></td>
<td>
<table width="100%">
<tr>
<td style="width:20%;">
<label id="lblApplyAfter" myId="lblApplyAfter" runat="server">Apply After</label>
</td>
<td></td>
</tr>
<tr>
<td>
<select id="sltApplyAfter" SkinID="drpFields" name="sltApplyAfter" runat="server" myId="sltApplyAfter">
<option value="-1">Charge</option>
</select>
</td>
<td>
<input type="checkbox" />Apply for All Services<input type="text" onkeypress="ValidateDecimalValue(event,this)"; onblur="ApplyForAllServices(this);" data-bind="attr: { 'class': ExtendedTaxTypeName }" /> %
</td>
</tr>
<tr>
<td colspan="2">
<table width="100%">
<tbody data-bind="foreach: TaxClasses">
<tr>
<td style="width:2%;">
<img src="../../Images/del_up.gif" onclick="HideMyChilds(this);" />
</td>
<td style="width:100%;" class="tdRepeaterHeaderBG" data-bind="text: ServiceClassName">

</td>
</tr>
<tr>
<td></td>
<td>
<table width="100%">
<thead>
<tr>
<td style="width:1%;">
<td style="width:24%;" class="tdRepeaterHeaderBG">Service Name</td>
<td style="width:75%;" class="tdRepeaterHeaderBG">Amount</td>
</tr>
</thead>
<tbody data-bind="foreach: TaxServices">
<tr>
<td style="width:1%;">
<td style="width:24%;" data-bind="text: ServiceName"></td>
<td style="width:75%;">
<input type="text" data-bind="value: ServiceRate, attr: { 'class': $parents[1].ExtendedTaxTypeName, 'id': $parents[1].ExtendedTaxTypeName + ServiceID }" />%
</td>
</tr>
<tr>
<td></td>
<td colspan="2">
<div style="font-size: 11px; width:98%;height:5px; border-top: 1px dotted gray;"> </div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</tbody>

问题是,当我为一个类中的税务服务提供 ServiceRate 时,它​​会更新为所有其他类中相同服务的文本字段。任何帮助都会很棒。

最佳答案

您的代码有几个问题。

  1. 首先,主要是装饰性的。您正在使用表格进行布局。仅当您真正需要表格数据时才应使用它们。在大多数情况下,Div 或列表要好得多,如果您需要布局某些内容,可以使用 CSS 边距。

  2. 您正在不断地混合不同的对象方案。

    • 其中之一是返回对象文字:

      function Foo() {
      return {
      Property: ko.observable(),
      }
      }

      此架构可以但不应该使用 new 来调用运算符。

    • 另一个是基于原型(prototype)的:

      function Foo() {
      var self = this;

      self.Property = ko.observable();
      }

      必须使用 new 调用此架构运算符。

    坚持一种模式是最容易的。通过 knockout ,后者在某些情况下更容易使用。

  3. 您并未对所有属性使用可观察量。对某些属性使用可观察量,而不对其他属性使用可观察量,这有点令人困惑。您必须返回源代码来确认每个属性。

  4. 您的对象模型没有考虑对象重用。您将相同的对象传递给每个 ServiceLevelRate ,所以当您更新 TaxService 时,同TaxService在所有其他TaxClass也会更新。

    对此的一个简单解决方案是将需要更新的字段分解为映射对象。

    // This part is constructed once, based on server data.
    function TaxService(data) {
    var self = this;

    self.ServiceID = ko.observable(data.ServiceID);
    self.ServiceName = ko.observable(data.ServiceName);
    }

    // This part is constructed for each TaxClassMapping
    function TaxServiceMapping(svc) {
    var self = this;

    self.TaxService = ko.observable(svc);
    self.ServiceRate = ko.observable("");
    }
  5. 最后;要根据复选框有条件地更新费率,您可以将其与 checked 绑定(bind)。 -捆绑。在ServiceLevelRate的订阅中-wide 速率,您只需检查该复选框是否已选中,然后再继续更新其他字段。

    self.ApplyForAll.subscribe(function (newValue) {
    if (self.ApplyForAllCheckBox()) {
    ko.utils.arrayForEach(self.Classes(), function (clsMapping) {
    ko.utils.arrayForEach(clsMapping.ClassServices(), function (svcMapping) {
    svcMapping.ServiceRate(newValue);
    });
    });
    }
    });

这是更新的 fiddle :

http://jsfiddle.net/MizardX/V8DTj/

我将模型缩小到重要部分,以使它们更易于使用。

<小时/>

为了使TaxServices仅显示某些 TaxClasses ,您可以过滤哪个 TaxService -您想要为每个 TaxClass 包含的对象.

function TaxClassMapping(taxClass, availableServices) {
var self = this;

self.TaxClass = ko.observable(taxClass);

var classID = taxClass.ServiceClassID();
var filtered = ko.utils.arrayFilter(availableServices, function (svc) {
// svc.ServiceClassID is a new property in TaxService
return svc.ServiceClassID() === classID;
});
var mapped = ko.utils.arrayMap(filtered, function (svc) {
return new TaxServiceMapping(svc);
});
self.ClassServices = ko.observableArray(mapped);
}

关于foreach - Knockout JS foreach嵌套,所有字段的值更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13988233/

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