【问题标题】:Revert an invalid value in knockout without subscriptions firing在不触发订阅的情况下恢复淘汰赛中的无效值
【发布时间】:2013-05-15 19:37:11
【问题描述】:

是否可以在不触发订阅的情况下使用自定义绑定处理程序(可能是扩展程序)恢复对视图模型的值更改

例如,假设您有一个数字字段,它只允许最大为 100 的值。如果有人输入 101,我们希望该值回退到之前的值,最重要的是触发任何订阅关于还原的值。

我正在尝试找到一种通用的方法来完成此操作,而无需编写自定义绑定处理程序,因为该处理程序本质上需要复制核心敲除代码来处理文本字段、选择字段等。

【问题讨论】:

    标签: javascript data-binding knockout.js


    【解决方案1】:

    是的,可以使用扩展器来完成,如下所示:

    ko.extenders.numeric = function(target, properties) {
        var result = ko.computed({
            read: target,
            write: function(newValue) {
                var current = target();
                var valueToWrite = newValue;
                if(properties) {
                    if(properties.maxNum && properties.maxNum < newValue) {
                        valueToWrite = current;
                    }
                    if(properties.minNum && properties.minNum > newValue) {
                        valueToWrite = current;
                    }
                }
    
                if(valueToWrite !== current) {
                    target(valueToWrite);
                } else {
                    target.notifySubscribers(valueToWrite);
                }
            }
        });
    
        result(target());
        return result;
    };
    

    这就是你使用它的方式:

    self.number = ko.observable().extend({numeric: { minNum: 50, maxNum: 100} });
    

    您可以在fiddle I've created 中进行测试。

    您可以评论 target.notifySubscribers(valueToWrite) 行,但如果您从外部更改该值(例如在 input 元素中),该值将不会更新回之前的值。

    【讨论】:

    • 感谢您的帖子。你和我实际上已经在同一点上。问题是,使用此解决方案,当值恢复到以前的值时会调用订阅,这实际上是我在这里试图避免的。我已经更新了我的问题以澄清。在此处查看您的小提琴的分叉版本以进行订阅调用:jsfiddle.net/9TkDk
    • 我不明白扩展器的概念。他们的文档在哪里?
    • @GotDibbs 你见过github.com/SteveSanderson/knockout/issues/711 吗?页面底部的解决方案可能有效,我不知道,但它似乎有点矫枉过正......
    • @Jalayn 这与我目前的发展方向相似,感谢分享。我稍后会发布我的解决方法,但我仍然希望有一个更优雅的解决方案。
    【解决方案2】:

    我走了@Jalayn 已经建议的相同路线,并最终做了类似于他回答中 cmets 中列出的问题的事情。我仍然不是这个的忠实拥护者,因为它要求您在订阅顶部检查该值是否实际上发生了变化,但至少这是可能的。

    完整的解决方案和 QUnit 测试发布在这里:https://github.com/gotdibbs/ko.extenders.filteredUpdate/

    完成这项工作的关键组件是使用计算的 observable 来“保护”视图模型免受不必要的更改的扩展器,以及扩展订阅的自定义函数在正常订阅之外工作无论值是否实际发生变化,都会在每次更改时触发。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-27
      • 2012-09-20
      • 2016-02-29
      • 2012-10-16
      • 2016-06-09
      • 2018-07-21
      • 2012-05-26
      相关资源
      最近更新 更多