如何将json接收到的ko.observable字符串解析为integer(number)值



我从服务器的json响应中获得ViewModel中的一个String。它看起来像这样:

"manual_setpoint": "200",

然后我需要在我的视图中显示它:

<div class="setpoint"  data-bind="text: vm.manual_setpoint(), style: { color: vm.state()? '#f00000' : '#777777'}"></div>

它需要显示为数字20(200/10(,因为有按钮可以增加和减少可观察到的值(例如201->20.1199->19.9(。这不是问题,因为我的可观察到在本地定义为数字。我是这样做的:

self.manual_setpoint.formatted = function() {
return (self.manual_setpoint() / 10);
};

然后在我的视图中显示manual_setup.formated((。我也有增加和减少这种可观察到的按钮,如下所示:

self.decSetpoint = function (observable) {
decrement(observable);
};
var decrement = function (observable) {
observable(observable() - 1);
};

现在,当服务器的响应是String时,我的方法就不再工作了。(例如,对于200+1,我得到2001等…(

如何以最简单优雅的方式处理这种情况?我需要在我的视图中显示正确的数字(所以对于200,我需要20(,我必须能够递增和递减与之前相同的可观测值

继续@johndoe的评论-恕我直言,我不同意。如果我误解了这个问题,很乐意删除答案。

如果该值在JSON中作为字符串发送,并通过ko.map.fromJs进行映射,那么它很有可能被映射为ko.observable("200")而不是ko.observable(200)

  1. 做一些关于映射的事情,将值转换为整数/浮点值,这将使decrement()函数按预期工作;或
  2. 更改递减函数以转换值,如下所示。

    var decrement = function (observable) {
    observable(parseInt(observable()) - 1);
    };
    

我也会更改

self.manual_setpoint.formatted = function() {
return (self.manual_setpoint() / 10);
};

self.manual_setpoint.formatted = ko.pureComputed(function() {
return (self.manual_setpoint() / 10);
});

这样,当manual_settit被更改时,格式化的版本也会被更新。

编辑

好吧,我纠正了需要为格式化函数使用pureComputed的问题。使用这个基本测试,似乎只需使用一个函数就可以按预期工作。很长一段时间以来,我一直认为,添加一个以某种方式包装可观察对象的函数会执行一次,如果在包装函数执行后(通常在绑定过程中(更新了包装的可观察对象,则不会更新。因此,当视图绑定到包装函数时,视图将不会更新,因为返回的函数是不可观察的。

此外,根据测试,parseInt似乎也不是真正需要的,可能是因为函数正在进行除法。我认为我的经验是基于添加,这会导致类似"20" + 1 = "201"而不是20 + 1 = 21

希望下面的测试能像帮助我一样帮助你。

var app = window.app || {};
app.vm = new Vm();
function Vm(){
var self = this;
self.manual_setpoint = ko.observable("200");
self.manual_setpoint.formatted =  function() {
return (parseInt(self.manual_setpoint()) / 10);
};
self.manual_setpoint.formattedAsComputed =  ko.pureComputed(function() {
return (self.manual_setpoint() / 10);
});
self.state = ko.observable(true);

self.increment = function(){
var value = parseInt(self.manual_setpoint()) + 1;
self.manual_setpoint(value.toString());
};
self.decrement = function(){
var value = parseInt(self.manual_setpoint()) - 1;
self.manual_setpoint(value.toString());
}
};
ko.applyBindings(app);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="setpoint"  data-bind="text: vm.manual_setpoint(), style: { color: vm.state()? '#f00000' : '#777777'}"></div>
<div class="setpoint"  data-bind="text: vm.manual_setpoint, style: { color: vm.state()? '#f00000' : '#777777'}"></div>
<div class="setpoint"  data-bind="text: vm.manual_setpoint.formatted(), style: { color: vm.state()? '#f00000' : '#777777'}"></div>
<div class="setpoint"  data-bind="text: vm.manual_setpoint.formatted, style: { color: vm.state()? '#f00000' : '#777777'}"></div>
<div class="setpoint"  data-bind="text: vm.manual_setpoint.formattedAsComputed, style: { color: vm.state()? '#f00000' : '#777777'}"></div>
<div class="setpoint"  data-bind="text: vm.manual_setpoint.formattedAsComputed(), style: { color: vm.state()? '#f00000' : '#777777'}"></div>
<button data-bind="click: vm.increment">Increment</button>
<button data-bind="click: vm.decrement">Decrement</button>
<br/>
<pre data-bind="text: ko.toJSON(vm)"></pre>

相关内容

最新更新