【发布时间】:2017-01-16 14:14:37
【问题描述】:
我正在尝试创建一个仅接受数字的数字输入框。
我的初始值方法是替换值并将其重新设置为自身。
订阅方式
function vm(){
var self = this;
self.num = ko.observable();
self.num.subscribe(function(newValue){
var numReg = /^[0-9]$/;
var nonNumChar = /[^0-9]/g;
if(!numReg.test(newValue)){
self.num(newValue.toString().replace(nonNumChar, ''));
}
})
}
ko.applyBindings(new vm())
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input type="text" data-bind="textInput: num" />
现在这种方法有效,但会添加另一个订阅事件循环,所以我尝试使用自定义绑定,以便我只能返回更新的值。新手,我尝试了一些东西,但不知道该怎么做。以下是我的尝试,但它不起作用。它甚至没有更新 observable。
自定义绑定尝试
ko.bindingHandlers.numeric_value = {
update: function(element, valueAccessor, allBindingsAccessor) {
console.log(element, valueAccessor, allBindingsAccessor())
ko.bindingHandlers.value.update(element, function() {
var value = ko.utils.unwrapObservable(valueAccessor());
return value.replace(/[^0-9]/g, '')
});
},
};
function vm() {
this.num = ko.observable(0);
this.num.subscribe(function(n) {
console.log(n);
})
}
ko.applyBindings(new vm())
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div>
<input type="text" data-bind="number_value: num, valueUpdate:'keyup'">
<span data-bind="text: num"></span>
</div>
所以我的问题是,我们可以使用自定义绑定来做到这一点吗?它是否比订阅更好?
编辑 1:
根据@user3297291 的回答,ko.extenders 看起来更像是我订阅方法的通用方式。我正在寻找一种方法(如果可能在 Knockout 中),它会在值设置为可观察之前清除值。
我参考了以下文章:
- How to update/filter the underlying observable value using a custom binding?
- How can i update a observable in custom bindings?
注意:在第一个示例中,他们使用 jQuery 来设置值。我想避免它并且只使用淘汰赛来做到这一点
【问题讨论】:
-
我认为自定义绑定将是订阅的更好替代方案,因为它是可重用的,因此您可以在需要相同功能的应用程序的其他地方使用它。看看这个 jsfiddle - jsfiddle.net/tdkhypnL/1 不确定这是不是你想要的。
-
@klikas 同意你的观点。我计划实现类似于
textInput但很少捆绑的东西。稍后将添加答案。此外,在您的小提琴中,字符在几分之一秒内可见,并且在某些情况下(如果输入 1 个字符),字符会被保留。 -
你是对的,我的解决方案并不完美,但我会在喜欢的时候尝试修复它,因为它有点匆忙只是为了说明这个概念:)
-
@klikas 我已经添加了一个答案。不确定它是否是最好的选择,但我想应该改进和使用。希望对您有所帮助。