【问题标题】:Knockout.js - Change other observables in viewmodel from extender or other way to do something similarKnockout.js - 从扩展器或其他方式更改视图模型中的其他可观察对象以执行类似操作
【发布时间】:2014-05-02 11:55:13
【问题描述】:

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

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

所以我开始在互联网上搜索如何实现这一点的提示和技巧。 首先我找到了this "confirmable" extender。如果他们选择的行数少于之前的值,它会帮助我显示一个确认对话框,但我发现无法从中与视图模型中的其他可观察对象进行交互。

所以我用 Google 搜索了更多内容,并找到了 the first answer from Michael Best here。使用“subscribeChanged”函数,我现在可以(在可确认扩展器完成它的部分之后)向可观察的订单行数组添加或删除行。

但是。我希望有一些更好的方法来实现这一点,以便在多个地方没有几乎完全相同的代码。因为现在我在扩展器中有这段代码

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();
}

我将this fiddle 与我今天的代码摘录放在一起。

我知道有些 if 语句不需要存在,但它们目前用于调试目的。当功能完成和测试时,我会查看要删除的内容,但欢迎任何指针(即使是与问题无关的指针)。

提前致谢,路德维格

【问题讨论】:

    标签: knockout.js knockout-2.0


    【解决方案1】:

    如果可以,您可以使用计算的 observable 来使用确认和更新:

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

    查看示例:http://jsfiddle.net/v3EAz/2/

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

    见:http://jsfiddle.net/v3EAz/3/

    【讨论】:

    • 但是如果你点击取消,下拉菜单仍然停留在“新值”。就像您选择 2 一样,它将添加 2 行。然后选择 1 并单击取消,即使没有删除任何行,下拉菜单仍将显示 1。这与我正在寻找的东西很接近:)
    • 答案已编辑。事实上,即使 observable 的值没有改变,select 也会保持它的新值。在这种情况下,您可以致电vm.numberOfOrderRows.valueHasMutated();
    • 我喜欢这个答案。保留请求的功能并删除 1 个步骤。感谢您的快速帮助
    【解决方案2】:

    扩展器可能不是最适合您的方案。似乎它让您跳过了不必要的麻烦,并且扩展器逻辑特定于您的视图模型/屏幕,它不是可以在其他情况下重用的通用扩展器。

    更简单的方法可能是使用敲除 observable 的 subscribe 函数来监听 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
    

    【讨论】:

    • 但如果用户取消确认,Ludvig 不想更新视图模型
    • 就像 GôTô 写的那样,我需要确认选择确实是故意的。你将如何编写这个处理函数?我使用扩展器的原因是因为它是搜索代码中的第一个点击,如果用户在确认中单击取消,它让我“中止”。我发现另一个订阅函数可以访问旧值和新值,但如果我没记错的话它已经设置了新值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多