[英]Create observable returning other observables as a single map
I have an own binding for numeric
inputs made in knockoutJS
which accepts only numbers. 我有一个单独的绑定,用于用
knockoutJS
进行的numeric
输入,该绑定仅接受数字。
To make big numbers I declare various instances of number in a NumberField
like: 为了生成大数字,我在
NumberField
声明了各种数字实例,例如:
var NumberField = function () {
var self = this;
self.maskFormat = "0";
self.firstNumber = ko.observable("");
self.secondNumber = ko.observable("");
self.thirdNumber = ko.observable("");
};
And 和
<input id="0" maxlength="1" type="tel" data-bind="numeric: firstNumber">
<input id="1" maxlength="1" type="tel" data-bind="numeric: secondNumber">
<input id="2" maxlength="1" type="tel" data-bind="numeric: thirdNumber">
This is working like a charm, but when I made submission, system is expecting a map with numbers. 这就像是一种魅力,但是当我提交时,系统期望一张带有数字的地图。 I achieved it IMHO in an ugly way:
我以丑陋的方式实现了恕我直言:
Added to NumberField
this attribute: 向
NumberField
添加此属性:
this.cleanNumber = ko.pureComputed(function () {
return this.firstNumber().toString() + this.secondNumber().toString() + this.thirdNumber().toString();
}, this);
And in the code, when I need to use it I must do this: 在代码中,当我需要使用它时,我必须这样做:
let unwrapNumbers = this.numbers().cleanNumber().split("").map(function (item){
return Number(item);
});
This is working, but... I'm pretty sure there is an easier and more straight way.... Any suggestions? 这是可行的,但是...我敢肯定,有一种更简单,更直接的方法....有什么建议吗?
I think it could help to split the computed in to two parts: 我认为这可能有助于将计算分为两部分:
Often it makes sense to split a computed in to several pure computeds that have a single clear data processing responsibility. 通常,将一个计算拆分为几个具有单个明确数据处理职责的纯计算是有意义的。
var NumberField = function () { var self = this; self.firstNumber = ko.observable(1); self.secondNumber = ko.observable(2); self.thirdNumber = ko.observable(3); self.orderedNumbers = ko.pureComputed(function() { return [self.firstNumber, self.secondNumber, self.thirdNumber].map(ko.unwrap); }); self.cleanedNumber = ko.pureComputed(function() { return self.orderedNumbers().join(""); }); }; var nf = new NumberField(); // If you want the numbers: console.log(nf.orderedNumbers()); // If you want the string console.log(nf.cleanedNumber());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
Now, I'm not sure what your requirements are, but you can take it one step further and use an observableArray
as the base data format: 现在,我不确定您的要求是什么,但是您可以将其进一步
observableArray
,并使用observableArray
作为基本数据格式:
var NumberField = function () { var self = this; self.numbers = ko.observableArray( [ko.observable(0), ko.observable(1), ko.observable(2)]); self.add = function() { self.numbers.push(ko.observable(self.numbers().length)); } self.unwrappedNumbers = ko.pureComputed(function() { return self.numbers().map(ko.unwrap); }); self.cleanedNumber = ko.pureComputed(function() { return self.unwrappedNumbers().join(""); }); }; ko.applyBindings(new NumberField());
label { display: block }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <div data-bind="foreach: numbers"> <label> <span data-bind="text: 'Number ' + $index()"></span> <input type="number" data-bind="textInput: $parent.numbers()[$index()]"> </label> </div> <button data-bind="click: add">add</button> <pre> Unwrapped:<code data-bind="text: unwrappedNumbers"></code> Cleaned:<code data-bind="text: cleanedNumber"></code> </pre>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.