【问题标题】:Knockout computed not firing subscription淘汰赛计算未触发订阅
【发布时间】:2015-08-17 10:03:56
【问题描述】:

这是我的代码:

self.convertedPrice = ko.computed(function () {
    console.debug('Calculating convertedPrice');
    if (self.ProductListPrice() != null && self.multiplicationFactor() != null) {
        return self.ProductListPrice() * self.multiplicationFactor();
    }

    return 0;
}).extend({notify:'always'});

self.convertedPrice.subscribe(function (newVal) {
    console.debug('convertedPrice subscription fired.');
    self.discountedPrice(parseFloat(newVal).toFixed(2));
});

self.ProductListPrice 更新时,self.convertedPrice 正确更新并写入第一个调试,但不会触发订阅,因此第二个调试语句永远不会写入,self.discountedPrice 也不会更新。

我现在已经通过将订阅的内容移动到计算代码中来解决这个问题,但我想了解为什么原始订阅不起作用。如果我手动更改了self.ProductListPriceself.multiplicationFactor,订阅就会触发,但是当它们因我的其余代码和用户输入而更改时,订阅不会触发。

任何想法我做错了什么?

【问题讨论】:

  • 如果你想让订阅在计算计算时触发,只需稍微柚木计算它。在此处使用deferEvaluation:true 示例jsfiddle.net/LkqTU/26144
  • 我已经尝试过推迟评估,同时尝试自己追踪这一点,但这没有任何区别。不过感谢您的想法。

标签: knockout.js


【解决方案1】:

我唯一的猜测是您在设置值时正在执行分配而不是调用可观察对象。下面的代码按预期工作。

function viewModel() {
  var self = {
    discountedPrice: ko.observable(),
    ProductListPrice: ko.observable(),
    multiplicationFactor: ko.observable()
  };
  self.convertedPrice = ko.computed(function() {
    console.debug('Calculating convertedPrice');
    if (self.ProductListPrice() != null && self.multiplicationFactor() != null) {
      return self.ProductListPrice() * self.multiplicationFactor();
    }

    return 0;
  }).extend({
    notify: 'always'
  });

  self.convertedPrice.subscribe(function(newVal) {
    console.debug('convertedPrice subscription fired.');
    self.discountedPrice(parseFloat(newVal).toFixed(2));
  });
  return self;
}

ko.applyBindings(viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div><label>List Price</label><input data-bind="value:ProductListPrice" /></div>
<div><label>Multiplier</label><input data-bind="value:multiplicationFactor" /></div>
<div><label>Converted</label> <span data-bind="text:convertedPrice"></span></div>
<div><label>Discounted</label> <span data-bind="text:discountedPrice"></span></div>

【讨论】:

  • 当你说做作业时,你的意思是使用(例如)self.multiplicationFactor = 3; 而不是self.multiplicationFactor(3);?我知道这不会发生,因为变量仍然是可观察的,但不确定我是否误解了你的意思。
  • @Tim 你理解正确。也有可能(虽然不太可能)你正在做类似self.multiplicationFactor = ko.observable(3) 的事情,这将使它成为一个可观察的,但不同的,未绑定的。我只能说你这里包含的代码没有问题。
  • 这是一个中肯的评论,我会检查我没有做过那样愚蠢的事情。
  • 有什么办法可以避免空检查吗?必须对每个计算的 observable 执行此操作似乎是一种反模式。我还没有找到解决办法。
  • 你可以用不同的方式编写它(例如return (obs1() || 0) * (obs2() || 0)),但我认为你不能绕过处理边缘情况。
猜你喜欢
  • 2018-12-27
  • 2013-12-04
  • 1970-01-01
  • 2012-09-20
  • 2016-02-29
  • 1970-01-01
  • 2018-07-21
  • 1970-01-01
  • 2015-01-04
相关资源
最近更新 更多