3

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

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

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

4

2 回答 2

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

您可以在我创建的小提琴中进行测试。

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

于 2013-05-15T20:03:10.760 回答
0

我沿着@Jalayn 已经建议的路线走,最后做了类似于他回答的评论中列出的问题。我仍然不是这个的忠实拥护者,因为它需要您在订阅顶部检查该值是否确实发生了变化,但至少这是可能的。

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

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

于 2013-05-15T20:50:31.553 回答