你能否强迫KnockoutJS重新评估绑定?

时间:2011-12-26 19:29:59

标签: mvvm knockout.js

我在一个页面中使用KnockoutJS和MVVM,如果它可以工作,我会使用它,但是我很难获得所有绑定来重新评估。例如,我有一个按钮,我想在满足某些条件时启用它:

<input type="submit" value="Purchase" data-bind="{enable: IsPurchaseValid}" />

IsPurchaseValid是我的viewmodel的计算函数:

viewModel.IsPurchaseValid = ko.computed(function() {
console.log("IsPurchaseValid: function entered...");

if (this.Duration() == null ||  this.Total() <= 0 || this.SelectedPackageId() < 0) {
    console.log("IsPurchaseValid: Something is missing...");
    return false;
}

return this.IsLocalityCountValid();
}, viewModel);

页面加载时,按钮被正确禁用,但从未重新评估。 IsLocalityCountValid是另一个计算函数,console.log语句表示它返回true。 Chrome的控制台没有显示脚本错误。

如何让启用绑定正确重新评估?我还有一个带有可见界限的跨度!IsLocalityCountValid永远不会变为可见。我觉得我错过了一些基本但却无法弄清楚它可能是什么的东西。

5 个答案:

答案 0 :(得分:2)

我有一个非常基本的repro启用它的工作原理。 (见下面的小提琴)

我建议你查看你的CSS。我遇到过这个问题一次因为我以某种方式删除了我的按钮:禁用了样式。我有一个按钮的样式,改变了背景颜色和字体颜色,但不知怎的,我 删除按钮:禁用样式....所以最终结果是,当它被禁用时,它看起来与启用时完全相同。

无论如何,您可以在此处测试启用/禁用按钮:您可以在此处自行测试:http://jsfiddle.net/johnpapa/wLKS6/

当没有CSS干扰时,问题没有发生在我身上。所以关键可能是确保你的CSS类首先表现。

答案 1 :(得分:1)

这可能是KO对您的计算值的评估未看到所有可观察值的情况,因此,不知道何时重新评估计算值。

例如,如果KO看到this.Duration不为null,则它可能不会评估if块中的其他observable,因此,如果其他可观察值发生更改,则可能无法重新评估您的计算值。

尝试使用此尺寸,看看它是否有效:

viewModel.IsPurchaseValid = ko.computed(function() {
   console.log("IsPurchaseValid: function entered...");

   // Evaluate all dependent observables up front.
   // This will let KO know which observables this computed value is dependent on.
   var duration = this.Duration();
   var total = this.Total();
   var packageId = this.SelectedPackageId();
   var islocalityCountValid = this.IsLocalityCountValid();
   if (duration == null || total <= 0 || packageId < 0) {
       console.log("IsPurchaseValid: Something is missing...");
       return false;
   }

   return isLocalityCountValid;
}, viewModel);

答案 2 :(得分:1)

您提到IsLocalityCountValid已更改为true,但您未提及Duration是否已更改为非nullTotal已更改为{{ 1}},>0已更改为SelectedPackageId。如果它们都没有改变,Knockout将不会重新评估>=0,因为它在需要评估computed之前返回false。有关更多详细信息,请参阅http://knockoutjs.com/documentation/computedObservables.html#how_dependency_tracking_works

答案 3 :(得分:1)

我刚注意到你的数据绑定语句用大括号括起来:

data-bind="{enable: IsPurchaseValid}"

尝试没有大括号:

data-bind="enable: IsPurchaseValid"

答案 4 :(得分:0)

所以看来这实际上是一个错误。使用原始代码,如果将其绑定到输入类型“submit”,它将不起作用,但如果将其绑定到输入类型“按钮”,它确实有效。我将它提交给了KnockoutJS谷歌小组。

修改: 我将接受这个作为答案,但在JSFiddle中按钮和提交工作。我的假设是必须存在一些跨jquery库冲突,因为我在实际站点中还有其他几个库在运行。