He preparado un pequeño jsfiddle aquí: jsfiddle.net/v8s176p2

Básicamente quiero aumentar y disminuir observable en pasos de 0.1 Pero debido a problemas de representación y precisión de números, los números a veces se muestran como: 1.3200000000000003 ... etc., quiero que solo se muestren y tengan valores con 1 punto decimal

¿Cómo codificaría exactamente esta misma funcionalidad en knockout.js, pero al no usar coma flotante? ¿Entonces mi valor inicial es 10 y en HTML se muestra como 1, si lo descifro (10-1 = 9) en html se muestra como 0.9? Este es probablemente el mejor enfoque para mi aplicación, ya que obtengo estos datos de un servidor en un dispositivo incorporado, por lo que sería mejor recibir el número como 200 y luego dividirlo por 10, pero cómo configurar esto en ko.js en mi ejemplo violín?

2
johndoe 29 oct. 2019 a las 11:38

3 respuestas

La mejor respuesta

Trabaje con enteros y haga división en el enlace de texto para mostrar el punto flotante. Esto mantiene los datos de respaldo como entradas para que no se acumulen errores.

data-bind="text: num1() / 10"

http://jsfiddle.net/xagup8vt/

0
caseyWebb 30 oct. 2019 a las 22:19

Otra forma es agregar un observable calculado a la propiedad observable como

var vm = function(){
    var self = this;
    self.num1 = ko.observable();
    self.num1.formatted = ko.computed(function(){ return  Math.round((self.num1()*10),0)/10; });
}

De esta manera, el formato está contenido con el modelo de vista y la conversión del objeto vm a JSON ignorará la función calculada formateada en la salida.

Para usarlo <p data-bind="text: num1.formatted"></p>

Otra opción es utilizar un observable computable grabable. He incluido ambas técnicas en el siguiente fragmento.

var increment = function(observable) {
  observable(observable() + 0.1);
};
var decrement = function(observable) {
  observable(observable() - 0.1);
};

var MyViewModel = function() {
  var self = this;
  self.num1 = ko.observable(0);
  self.num1.formatted = ko.computed(function() {
    return Math.round((self.num1() * 10), 0) / 10;
  });
  var num2BackingProperty = ko.observable(0);
  self.num2 = ko.computed({

    read: function() {
      return num2BackingProperty();
    },
    write: function(value) {
      num2BackingProperty(Math.round((value * 10), 0) / 10);
    },
    owner: self
  })

  this.incrementNum = function(observable) {
    // passing the observable by reference to the helper function
    increment(observable);
  };

  this.decrementNum = function(observable) {
    decrement(observable);
  };
}

ko.applyBindings(new MyViewModel());
h3 {
  font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>
<button data-bind="click: incrementNum.bind($root, num1)">Increment Num1</button>
<button data-bind="click: decrementNum.bind($root, num1)">Decrement Num1</button>
<h3>
  Formatted
</h3>
<p data-bind="text: num1.formatted"></p>
<h3>
  Unformatted
</h3>
<p data-bind="text: num1"></p>
<br/>
<br/>
<button data-bind="click: incrementNum.bind($root, num2)">Increment Num2</button>
<button data-bind="click: decrementNum.bind($root, num2)">Decrement Num2</button>

<h3>
  Writable Computed
</h3>
<p data-bind="text: num2"></p>
<br/>
<h3>
  View Model Json
</h3>

<pre data-bind="text: ko.toJSON($root)"></pre>

http://jsfiddle.net/gonefishern/yo2nurf8/30/

0
Nathan Fisher 31 oct. 2019 a las 06:18

Podría crear un enlace personalizado, algo como esto

ko.bindingHandlers.numericText = {
    update: function (element, valueAccessor, allBindingsAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        var formattedValue = value.toFixed(2);
        ko.bindingHandlers.text.update(element, function () { return formattedValue; });
    }
};

Allí puede formatear el valor como desee y luego usarlo así:

<p data-bind="numericText: num1"></p>
0
Daniel 29 oct. 2019 a las 08:55