使knockout侦听非击键结果的值更改

Make knockout listen to values changes which are not a result of a keystroke

本文关键字:结果 knockout      更新时间:2023-09-26
self.totalHours = ko.pureComputed(function() {
        var start=self.num1;
        var end=self.num2;
        return start+end; 
});
<input   type="text" data-bind="textInput: start">
<input  type="text" data-bind="textInput: end">
<input  type="text" data-bind='text: totalHours()'>

上面第一个是我的viewmodel的一部分,第二个是我的model的一部分。num1,num2是可观测对象。每次我手动更改前两个输入中的值时,第三个输入立即更新;但是,当值被代码改变时,knockout不会侦听这些变化,total也不会更新。我怎样才能迫使knockout倾听代码引起的变化呢?

你可以在这里修复和改进很多东西:

  • 计算值将在其方法中使用的可观察对象发生变化时重新评估:self.num1和/或self.num2需要被观察使用()
  • 评估
  • 如果你想绑定<input>的值,你必须使用valuetextInput数据绑定;text绑定将工作。
  • 如果你想写一个计算,你必须指定一个write方法。您必须告诉knockout如何更新computed的依赖项,以确保所有值相加。(例如:设置totalHours可以设置num1totalHours, num20)
  • 你绑定了startend,而你的视图模型属性被命名为num1num2
  • 当使用valuetextInput时,用户输入将以字符串形式返回。如果你想在任何数学中使用它们,你需要将字符串解析为数字。
现在所有的代码都可以正常工作了,您可以通过输入或通过代码来更新视图模型的值:

var ViewModel = function() {
  var self = this;
  
  self.num1 = ko.observable(0);
  self.num2 = ko.observable(0);
  
  self.totalHours = ko.pureComputed(function() {
    var start = parseFloat(self.num1());
    var end = parseFloat(self.num2());
    return start + end;
  });
  
};
var vm = new ViewModel();
ko.applyBindings(vm);
// Updating your values from code:
vm.num1(1);
vm.num2(2);
// Whenever the values need to be updated via js,
// you should change the source values, _not_ the
// <input>'s values. Worst case scenario, you'll
// have to do something like this:
var updateNum1ViaDOM = function() {
  ko.dataFor(document.querySelector("input")).num1(5);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input type="text" data-bind="textInput: num1">
<input type="text" data-bind="textInput: num2">
<span data-bind='text: totalHours'></span>


注意:使用扩展器强制num1num2为数字可能更好:实际示例1:强制输入为数字

不确定是否是复制粘贴问题,但您发布的代码将无法按预期工作。我已经更新了这个例子,当改变一个可观察对象的值时,它必须作为参数传递,以免覆盖可观察对象

self.start = ko.observable();
self.end = ko.observable();
self.totalHours = ko.computed(function() {
    return self.start() + self.end();
});
<input   type="text" data-bind="textInput: start">
<input  type="text" data-bind="textInput: end">
<input  type="text" data-bind='text: totalHours()'>
//Then when changing the value by code
var newValue = 42;
model.start(newValue); //assuming you are making the change outside your viewmodel

*注意到这段代码会在编辑绑定到totalHours的输入时抛出异常,因为它没有定义写处理程序。这是一个单独的问题。