你能强制 KnockoutJS 重新评估绑定吗?

发布于 2024-12-22 17:14:19 字数 798 浏览 0 评论 0原文

我在页面中使用 KnockoutJS 和 MVVM,并且大多数情况下它可以工作,但我无法重新评估所有绑定。例如,我有一个按钮,我想在满足某些条件时启用:

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

IsPurchaseValid 是我的视图模型的计算函数:

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 的跨度,但它永远不会变得可见。我觉得我错过了一些基本的东西,但不知道它可能是什么。

I'm using KnockoutJS and MVVM in a page and most if it works, but I'm having trouble getting all the bindings to reevaluate. For instance, I have a button that I want to enable when certain criteria are met:

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

IsPurchaseValid is a computed function of my 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);

The button is correctly disabled when the page loads, but is never reevaluated. IsLocalityCountValid is another computed function and the console.log statements indicate it is returning true. Chrome's console shows no scripting errors.

How do I get the enable binding to reevaluate correctly? I also have a span with visible bound to !IsLocalityCountValid that never turns visible. I feel like I'm missing something basic but can't figure out what it may be.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

终遇你 2024-12-29 17:14:19

我有一个非常基本的重现,可以在它起作用的地方启用。 (见下面的小提琴)

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

无论如何,您可以在这里测试按钮启用/禁用:您可以在这里自己测试一下:http://jsfiddle。 net/johnpapa/wLKS6/

当没有 CSS 干扰时,这个问题不会发生在我身上。因此,关键可能是确保您的 CSS 类首先表现良好。

I have a very basic repro for enable where it works. (see fiddle below)

I suggest you check your CSS. I ran into this problem once because I had somehow deleted my button:disabled style. I had a style for the button that changed the background color and the font color, but somehow I
removed the button:disabled style .... so the net result was that when it was disabled, it looked exactly the same as when it was enabled.

Anyway, you can test the button enabling/disabling here: You can test this for yourself here: http://jsfiddle.net/johnpapa/wLKS6/

The problem did not happen to me when there is no CSS to interfere. So the key may be to make sure your CSS classes are behaving first.

请止步禁区 2024-12-29 17:14:19

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

例如,如果 KO 看到 this.Duration 不为 null,它可能不会评估 if 块中的其他可观察量,因此,如果其他可观察量发生变化,可能不知道重新评估您的计算值。

试一下尺寸,看看是否有效:

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);

This may be a case where KO's evaluation of your computed value doesn't see all the observables, and thus, doesn't know when to reevaluate the computed value.

For example, if KO sees that this.Duration is not null, it may not evaluate the other observables in your if block, and thus, may not know to reevaluate your computed value if those other observables change.

Try this on for size, see if it works:

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);
染墨丶若流云 2024-12-29 17:14:19

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

You mention that IsLocalityCountValid has changed to true, but you don't mention whether Duration has changed to non-null, Total has changed to be >0, and SelectedPackageId has changed to >=0. If none of them change, Knockout won't re-evaluate the computed because it returned false before needing to evaluate IsLocalityCountValid. See http://knockoutjs.com/documentation/computedObservables.html#how_dependency_tracking_works for some more details.

相思碎 2024-12-29 17:14:19

我刚刚注意到您的数据绑定语句包含在大括号中:

data-bind="{enable: IsPurchaseValid}"

尝试不使用大括号:

data-bind="enable: IsPurchaseValid"

I just noticed that your databinding statement is wrapped in curly braces:

data-bind="{enable: IsPurchaseValid}"

Try without the curly braces:

data-bind="enable: IsPurchaseValid"
意犹 2024-12-29 17:14:19

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

编辑
我将接受这个答案,但在 JSFiddle 中按钮和提交工作。我的假设是,一定存在一些跨 jquery 库冲突,因为我在实际站点中还有其他几个库在使用。

So it appears that this is actually a bug. With the original code, if you bind it to an input type "submit" it does not work, but if you bind it to an input type "button" it does work. I submitted it to the KnockoutJS google group.

EDIT:
I'm going to accept this as the answer, but in JSFiddle both button and submit work. My assumption is that there must be some cross-jquery library conflicts as I have several other libraries at play in the actual site as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文