我对Durandal和Knockout很新,我遇到了一个问题,我无法弄清楚如何解决。
我有一张信用卡表的视图。每行有两个名为Dimension1Key和Dimension2Key的嵌套下拉列表 - 它们是从GetDimensionMatrix ajax调用填充的。
信用额度foreach填充在for循环中,其中两个下拉列表定义为可观察 - 而Dimension2的数据计算为ko.compute。
最初使用正确的值选择正确填充表格和下拉列表 - 但嵌套无法正常工作。无论我更改哪个Dimension1下拉列表, self 的引用都是表格中的最后一行 - 因此使用最后一行的选定值填充相应Dimension1的Dimension2。 如果再次更改Dimension1值,则不会发生任何事情 - 对计算函数的引用被破坏。但是,如果我更改最后一行的Dimension1的值,则先前更改的行Dimension2的值会更改 - 就好像它的引用现在已连接到最后一行。
我很确定问题是视图模型中循环中的 self - 以及它所存在的上下文 - 但我无法理解解决方案。
有任何帮助吗? : - )
查看:
<section>
<h2 data-bind="html:displayName"></h2>
<table class="table">
<tbody data-bind="foreach: creditCardLines">
<tr>
<td class="date" data-bind="text: Date"></td>
<td class="date" data-bind="text: DocumentNo"></td>
<td data-bind="text: Description"></td>
<td><select data-bind="options: $parent.dimension1List, optionsText: 'DimensionValue', optionsValue: 'DimensionKey', value: Dimension1Key"></select></td>
<td><select data-bind="options: dimension2List, optionsText: 'DimensionValue', optionsValue: 'DimensionKey', value: Dimension2Key"></select> </td>
<td data-bind="text: Currency"></td>
<td data-bind="text: CurrencyAmount"></td>
<td data-bind="text: ExchangeRate"></td>
<td data-bind="text: AmountLCY"></td>
<td data-bind="text: Comment"></td>
<td data-bind="text: ApprovedEmployee"></td>
<td data-bind="text: Id"></td>
</tr>
</tbody>
</table>
</section>
视图模型:
define(function (require) {
var submit = function () {
this.displayName = 'Rejseafregning';
this.creditCardLines = ko.observableArray();
var me = this;
this.activate = function () {
return $.when(
$.get('/submit/GetCreditCardLines'),
$.get('/submit/GetDimensionMatrix')
)
.then(function (creditCardLines, dimension1List) {
me.dimension1List = dimension1List[0].Data;
for (var i = 0; i < creditCardLines[0].Data.length; i++) {
var self = creditCardLines[0].Data[i];
self.Dimension1Key = ko.observable(creditCardLines[0].Data[i].Dimension1Key);
self.Dimension2Key = ko.observable(creditCardLines[0].Data[i].Dimension2Key);
self.dimension2List = ko.computed(function () {
for (var j = 0; j < me.dimension1List.length; j++) {
if (me.dimension1List[j].DimensionKey === self.Dimension1Key()) {
return me.dimension1List[j].DimensionNext;
}
}
});
me.creditCardLines.push(self);
}
});
};
};
return submit;
});
答案 0 :(得分:2)
创建ko.computed
时,您可以传入第二个参数,该参数在计算计算值时控制this
的值。
当您创建dimension2List
计算时,您希望将当前self
作为第二个参数传递,然后在方法中使用this
,如:
self.dimension2List = ko.computed(function () {
for (var j = 0; j < me.dimension1List.length; j++) {
if (me.dimension1List[j].DimensionKey === this.Dimension1Key()) {
return me.dimension1List[j].DimensionNext;
}
}
}, self);
否则,重新计算计算值时self
的值最终成为self
设置为(最后一行)的最后一个值,基于闭包在JS中的工作方式。
使用computed
的第二个参数可确保将该特定值用作上下文。