在没有订阅触发的情况下在knockout中恢复无效值

时间:2013-05-15 19:37:11

标签: javascript data-binding knockout.js

是否可以使用除自定义绑定处理程序(可能是扩展程序)之外的其他内容将值更改还原到视图模型而不激活订阅

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

我正在尝试找到一种完成此操作的通用方法,而无需编写自定义绑定处理程序,该处理程序固有地需要重复核心挖空代码来处理文本字段,选择字段等。

2 个答案:

答案 0 :(得分:3)

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

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元素中),则该值不会更新回原来的值。

答案 1 :(得分:0)

我走了@Jalayn已经建议的路线,并最终做了类似于他的回答评论中列出的问题。我仍然不是这方面的忠实粉丝,因为它要求您在订阅的顶部检查以查看该值是否实际已更改,但至少可以。

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

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