Knockout.js js-从extender或其他方式更改viewmodel中的其他观察值以执行类似操作

Knockout.js js-从extender或其他方式更改viewmodel中的其他观察值以执行类似操作,knockout.js,knockout-2.0,Knockout.js,Knockout 2.0,我以前做过一些简单的淘汰赛,但这次感觉更复杂。 一位客户希望能够通过下拉菜单控制表单中的订单行数。我问他们为什么不需要常规的添加按钮,但他们说这会让他们更好地了解所有内容都已填写 我有一个observable来保存下拉列表中的值,还有一个observable来保存订单行,但是我必须确认当新值小于前一个值时选择是有意的 因此,我开始在互联网上搜寻如何实现这一目标的技巧和窍门。 首先我发现了。它帮助我显示了一个确认对话框,如果他们选择的行数小于之前的值,但我发现没有办法从中与viewmodel中的其

我以前做过一些简单的淘汰赛,但这次感觉更复杂。 一位客户希望能够通过下拉菜单控制表单中的订单行数。我问他们为什么不需要常规的添加按钮,但他们说这会让他们更好地了解所有内容都已填写

我有一个observable来保存下拉列表中的值,还有一个observable来保存订单行,但是我必须确认当新值小于前一个值时选择是有意的

因此,我开始在互联网上搜寻如何实现这一目标的技巧和窍门。 首先我发现了。它帮助我显示了一个确认对话框,如果他们选择的行数小于之前的值,但我发现没有办法从中与viewmodel中的其他观察对象交互

所以我在谷歌上搜索了更多,找到了。使用subscribeChanged函数,我现在可以在confirmable extender完成它的一部分后将行添加或删除到order行的可观察数组中

不过。我希望有更好的方法来实现这一点,这样就不会在多个地方出现几乎完全相同的代码。因为现在我在扩展器中有了这个代码

if (!isValidateInteger(current) && isValidateInteger(newValue)) {
    target(newValue);
    // TODO: Add rows to vm.orderRows so the count reflects newValue
}
这个代码在subscribeChanged函数中

if (!isValidateInteger(current) && isValidateInteger(newValue)) {
    // NOTE: Add rows to vm.orderRows so the count reflects newValue
    difference = (newValueInt - currentInt);
    message += '<br />Add ' + difference + ' row(s).';
    for (var i = 0; i < difference; i++) {
        vm.orderRows().push(new OrderRow());
    }
    vm.orderRows.valueHasMutated();
}
我把今天的代码摘录放在一起

我知道一些if语句不需要在那里,但它们目前是用于调试的。我将在功能完成并测试后查看要删除哪些,但欢迎提供任何指针,即使这些指针与问题无关


提前感谢,Ludvig

扩展器可能并不最适合您的场景。它似乎让您跳过了不必要的障碍,而且扩展程序逻辑特定于您的viewmodel/screen,它不是一个可以在其他情况下重用的通用扩展程序

一种更简单的方法可能是使用knockout observable的函数来监听numberOfOrderRows的更改,并做出相应的反应

var vm = {
    numberOfOrderRows: ko.observable(''),
    orderRows: ko.observableArray(),
};

vm.numberOfOrderRows.subscribe(
... todo write a numberOfOrderRowsChanged handler function to do the following:
1) validate the new value
2) perform any user confirmation logic
3) if successful, update the orderRows observable
4) if unsuccessful, restore the previous value to numberOfOrderRows

如果确定,您可以使用计算的可观测值来使用确认和更新:

vm.enhancedNumberOfOrderRows = ko.computed({
    read: vm.numberOfOrderRows,
    write: function(newValue) {
        //do all your checks, update vm.numberOfOrderRows only if you want
    }
});
参见示例:

编辑:您必须调用vm.numberOfOrderRows.valueHasMutated;如果用户取消更新选择的值


请参阅:

但如果用户取消了确认,Ludvig不想更新viewmodel,如GôTô写道,我需要确认选择确实是故意的。您将如何编写此处理程序函数?我使用扩展器的原因是,它是搜索代码的第一批点击中的一个,如果用户在确认时单击“取消”,它会让我中止。我发现另一个subscribe函数可以访问旧值和新值,但是如果我记得正确的话,它已经设置了新值。但是如果单击“取消”,下拉列表仍然保持在新值。如中所示,如果选择2,它将添加2行。然后选择1并单击“取消”,即使未删除任何行,下拉列表仍将显示1。这和我要找的差不多了tho:答案已编辑。事实上,即使可观测值不变,select也会保留其新值。您可以调用vm.numberOfOrderRows.valueHasMutated;那样的话,我喜欢这个答案。保留请求的功能并删除1个步骤。谢谢你的快速帮助