在不触发订阅的情况下,在淘汰中恢复无效值



是否有可能使用自定义绑定处理程序(可能是扩展程序)以外的东西还原值更改到视图模型而不触发订阅?

例如,假设您有一个数字字段,它只允许值不超过100。如果有人输入101,我们希望该值回落到之前的值,最重要的是而不是对恢复的值触发任何订阅。

我试图找到一种通用的方式来完成这一点,而不必编写一个自定义绑定处理程序,本质上需要重复的核心敲除代码来处理文本字段,选择字段等

是的,它可以用扩展器完成,像这样:

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

你可以在我创建的小提琴中测试。

您可以注释target.notifySubscribers(valueToWrite)行,但会发生的情况是,如果您从外部更改该值(如在input元素中),该值将不会更新回前一个。

我采取了@Jalayn已经建议过的相同路线,并最终做了类似于他的回答的评论中列出的问题。我仍然不太喜欢这种方法,因为它需要你在订阅的顶部检查的值是否真的改变了,但至少这是可能的。

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

实现此功能的关键组件是一个扩展器,它使用计算观察对象来"保护"视图模型免受不必要的更改,以及一个将订阅扩展到的自定义函数。是一个普通订阅,无论值是否实际发生更改,都会在每次更改时触发。

最新更新