我对numeric中的knockoutJS输入具有自己的绑定,该绑定仅接受数字。

为了生成大数字,我在NumberField中声明了各种数字实例,例如:

var NumberField = function () {
  var self = this;
  self.maskFormat = "0";
  self.firstNumber = ko.observable("");
  self.secondNumber = ko.observable("");
  self.thirdNumber = ko.observable("");
};




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


这就像一种魅力,但是当我提交时,系统期望一张带有数字的地图。我以丑陋的方式实现了恕我直言:

NumberField中添加了以下属性:

this.cleanNumber = ko.pureComputed(function () {
    return this.firstNumber().toString() + this.secondNumber().toString() + this.thirdNumber().toString();
}, this);


在代码中,当我需要使用它时,我必须这样做:

let unwrapNumbers = this.numbers().cleanNumber().split("").map(function (item){
    return Number(item);
});


这是可行的,但是...我敢肯定有一种更简单,更直接的方法....有什么建议吗?

最佳答案

我认为这可能有助于将计算分为两部分:


获取要按顺序包含的数字
根据顺序值创建一个字符串


通常,将一个计算拆分为几个具有单个明确数据处理职责的纯计算是有意义的。



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>





现在,我不确定您的要求是什么,但是您可以将其进一步前进,并使用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>

关于javascript - 创建可观测的返回其他可观测对象作为单个 map ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41715231/

10-11 13:23