gpt4 book ai didi

javascript - Knockout JS中的数字输入框

转载 作者:可可西里 更新时间:2023-11-01 02:24:03 24 4
gpt4 key购买 nike

我正在尝试创建一个只接受数字的数字输入框。

我的初始值方法是替换值并将其重新设置为自身。

订阅方式

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" />

现在这种方法可行,但会添加另一个订阅事件循环,因此我尝试使用自定义绑定(bind),以便我只能返回更新后的值。新手,我尝试了一些但不知道该怎么做。以下是我的尝试,但它不起作用。它甚至不更新 observable。

自定义绑定(bind)尝试

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>

所以我的问题是,我们可以使用自定义绑定(bind)来做到这一点吗?这种方法是否比订阅方法更好?


编辑 1:

根据 @user3297291的回答,ko.extenders 看起来更像是我的订阅方法的通用方式。我正在寻找一种方法(如果可能的话,在 Knockout 中),它会在将值设置为可观察之前清除值。


我引用了以下文章:

注意:在第一个示例中,他们使用 jQuery 来设置值。我想避免它并仅使用 knockout 来完成

最佳答案

我赞成使用扩展器作为 user3297291的答案。

Extenders 是一种灵活的方式来格式化或验证 observables,并且更可重用。

这是我对数字扩展器的实现

//Extender

ko.extenders.numeric = function(target, options) {
//create a writable computed observable to intercept writes to our observable
var result = ko.pureComputed({
read: target, //always return the original observables value
write: function(newValue) {
var newValueAsNum = options.decimals ? parseFloat(newValue) : parseInt(newValue);
var valueToWrite = isNaN(newValueAsNum) ? options.defaultValue : newValueAsNum;
target(valueToWrite);
}
}).extend({
notify: 'always'
});

//initialize with current value to make sure it is rounded appropriately
result(target());

//return the new computed observable
return result;
};

//View Model

var vm = {
Product: ko.observable(),
Price: ko.observable().extend({
numeric: {
decimals: 2,
defaultValue: undefined
}
}),
Quantity: ko.observable().extend({
numeric: {
decimals: 0,
defaultValue: 0
}
})
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

编辑

我明白你的意思了,如何使用正则表达式自定义绑定(bind)来提高可重用性?

像这样。

function regExReplace(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {

var observable = valueAccessor();
var textToReplace = allBindingsAccessor().textToReplace || '';
var pattern = allBindingsAccessor().pattern || '';
var flags = allBindingsAccessor().flags;
var text = ko.utils.unwrapObservable(valueAccessor());
if (!text) return;
var textReplaced = text.replace(new RegExp(pattern, flags), textToReplace);

observable(textReplaced);
}

ko.bindingHandlers.regExReplace = {
init: regExReplace,
update: regExReplace
}


ko.applyBindings({
name: ko.observable(),
num: ko.observable()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>


<input type="text" data-bind="textInput : name, regExReplace:name, pattern:'(^[^a-zA-Z]*)|(\\W)',flags:'g'" placeholder="Enter a valid name" />
<span data-bind="text : name"></span>
<br/>
<input class=" form-control " type="text " data-bind="textInput : num, regExReplace:num, pattern: '[^0-9]',flags: 'g' " placeholder="Enter a number " />
<span data-bind="text : num"></span>

关于javascript - Knockout JS中的数字输入框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39394445/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com