KnockoutJS拦截到一个小数位

我知道有人提出了这方面的变化,但我的要求是,不需要格式化/舍入输入的值,我甚至不允许用户在小数点后输入多个数字。 我有一些适用于decimalFormatter绑定处理程序的东西,但它很笨重 – 也就是说,它允许你输入像’20这样的值。 并且由于我编写正则表达式的方式,您无法擦除所有值。 我意识到我可以修改它以接受整个条目的可选数字,但我真正想要的是,如果用户删除该值,它将恢复为0.0。 并且,允许他们进入’20’。 然后选项卡(onblur)并将其重新格式化为20.0,使其看起来更完整。 目前,如果用户输入’20’。 然后保存表单,它确实存储整数值20,当你重新打开/检索数据库中的值时,它显示20.0,所以它在重新加载时看起来很好。

我想过添加一个onblur事件,但是我们不想在覆盖被淘汰的数据绑定时做到这一点。 我们希望保持ko视图模型的所有约束,因此这不是一个选项。 我也看到一些建议计算的observable(例如这个SO post ),但我的绑定已经做到了。 第二个想法,敲门事件绑定是否可以去这里?

HTML:

 

JavaScript的:

 ko.bindingHandlers.decimalFormatter = { init: function (element, valueAccessor) { var initialValue; //$(element).on('keydown', function (event) { $(element).keydown(function (event) { initialValue = $(element).val(); // Allow: backspace, delete, tab, escape, and enter if (event.keyCode == 46 || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 27 || event.keyCode == 13 || // Allow: Ctrl combinations (event.ctrlKey === true) || // Allow decimal/period (event.keyCode === 110) || (event.keyCode === 190) || // Allow: home, end, left, right (event.keyCode >= 35 && event.keyCode <= 39)) { // let it happen, don't do anything return; } else { // Ensure that it is a number and stop the keypress if (event.shiftKey || (event.keyCode  57) && (event.keyCode  105)) { event.preventDefault(); } } }); $(element).keyup(function (event) { if (!$(element).val().match(/^\d+\.?\d?$/)) { event.preventDefault(); $(element).val(initialValue); } else return; }); var observable = valueAccessor(); var interceptor = ko.computed({ read: function () { return formatWithComma(observable(), 1); }, write: function (newValue) { observable(reverseFormat(newValue, 1)); } }); if (element.tagName == 'INPUT') ko.applyBindingsToNode(element, { value: interceptor }); else ko.applyBindingsToNode(element, { text: interceptor }); }, update: function (element, valueAccessor) { } } // Formatting Functions function formatWithComma(x, precision, seperator) { var options = { precision: precision || 2, seperator: seperator || '.' } var formatted = parseFloat(x, 10).toFixed(options.precision); var regex = new RegExp('^(\\d+)[^\\d](\\d{' + options.precision + '})$'); formatted = formatted.replace(regex, '$1' + options.seperator + '$2'); return formatted; } function reverseFormat(x, precision, seperator) { var options = { precision: precision || 2, seperator: seperator || '.' } var regex = new RegExp('^(\\d+)[^\\d](\\d+)$'); var formatted = x.replace(regex, '$1.$2'); return parseFloat(formatted); } var viewModel = function () { var self = this; self.percentage = ko.observable(20.0); }; var vm = new viewModel(); ko.applyBindings(vm); 

的jsfiddle

好吧,我使用AUTONUMERIC插件进行数字格式化,这是可靠和令人敬畏的。

我只是根据你的要求做了一个小样, 在这里检查一下

查看型号:

 var vm = function(){ this.Amount=ko.observable(""); this.OnloadAmount=ko.observable(143); //onLoad Test ko.bindingHandlers.autoNumeric = { init: function (el, valueAccessor, bindingsAccessor, viewModel) { var $el = $(el), bindings = bindingsAccessor(), settings = bindings.settings, value = valueAccessor(); $el.autoNumeric(settings); $el.autoNumeric('set', parseFloat(ko.utils.unwrapObservable(value()), 10)); $el.change(function () { value(parseFloat($el.autoNumeric('get'), 10)); }); }, update: function (el, valueAccessor, bindingsAccessor, viewModel) { var $el = $(el), newValue = ko.utils.unwrapObservable(valueAccessor()), elementValue = $el.autoNumeric('get'), valueHasChanged = (newValue != elementValue); if ((newValue === 0) && (elementValue !== 0) && (elementValue !== "0")) { valueHasChanged = true; } if (valueHasChanged) { $el.autoNumeric('set', newValue); } } }; } ko.applyBindings(new vm()); 

查看:

  

这里mDec:1将数字限制为1和asep:''十进制数asep:''表示它不会用逗号等来编号

PS:我们可以限制输入无效字符并轻松完成许多其他操作。

有关完整参考,请点击此处