是否有可能使用自定义绑定处理程序(可能是扩展程序)以外的东西还原值更改到视图模型而不触发订阅?
例如,假设您有一个数字字段,它只允许值不超过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/.
实现此功能的关键组件是一个扩展器,它使用计算观察对象来"保护"视图模型免受不必要的更改,以及一个将订阅扩展到的自定义函数。是一个普通订阅,无论值是否实际发生更改,都会在每次更改时触发。