【问题标题】:KnockoutJS Binding not updating in checkbox click eventKnockoutJS 绑定未在复选框单击事件中更新
【发布时间】:2020-10-16 04:14:08
【问题描述】:

我在使用 KnockoutJS 时遇到了问题,数据绑定似乎没有按预期更新。

在我的视图模型中,我有一个对象数组,它的 Enabled 属性初始化为 True,并且将该属性绑定为在带有点击处理程序 CheckItems 的复选框上启用:

self.Answers(data.filter(function (step) {
  if (step.Type == 0) {
    step.Enabled = true;
    return true;
  }
  else {
    return false;
  }
}));

...
<ul data-bind="foreach: $root.Answers">
  <input type="checkbox" data-bind="click: $root.CheckItems, ...,  enable: Enabled>
</ul>

一切正常,花花公子,直到 CheckItems 处理程序运行并且我尝试将 Enabled 属性设置为 false:

self.CheckItems = function (step) {
  ...
  self.Answers().forEach(function (option) {
    <call my handler>.done(function (data) {
        option.Enabled = data;
      }
    );
  });
  // EDIT: added valueHasMutated() call here
  self.Answers.valueHasMutated();
  return true;
}

当我点击返回 true 时,我可以检查 self.Answers() 对象,它显示应该禁用的答案具有 Enabled = false(正确),但是一旦我们成为处理程序,所有复选框都不是禁用,然后单击存在的任何其他复选框并通过处理程序显示 Enabled 属性似乎已重置为 True。我三重检查并确保在单击复选框之间的代码中的任何地方都没有其他任何内容触及 Enabled 属性。

绑定本身似乎也在工作,因为当我将初始启用设置切换为 false 时,所有复选框都被禁用。

我正在对脚本中的其他地方的 self.Answers 数组进行更改,并且这些都可以通过,当进行更改时,它会进入 knockout-latest.debug.js 并进入 notifySubscribers 函数进行适当的更新。或许淘汰赛中输入字段的点击事件有什么特别之处?

有什么想法吗?总体而言,对于 Knockout 来说仍然相当新,但我认为这就是重点,我可以更新 Answers() 可观察数组中的一个属性,它会在相应的 UI 中更新。

编辑:基于 cmets,我在编辑完成后尝试调用 valueHasMutated(),但仍无法正确更新。

Edit2:尝试复制 self.Answers 数组,执行处理程序调用以更新 Enabled,然后使用 self.Answers(newAnswers) 进行设置,结果相同。

【问题讨论】:

  • yourObservable.valueHasMutated(),在你做出改变后试试这个。我没有用你的代码测试过,但这可能会解决你的问题
  • 原因似乎是您正在更改包含在您可观察对象中的值,而 ko 不知道该更改。一种解决方案(正如@TEK 已经提到的)应该是使用valueHasMutated()
  • 谢谢,我尝试添加 self.Answers.valueHasMutated(),但不幸的是没有骰子。我开始调试调用 valueHasMutated() 时输入的 Knockout 代码,Knockout 有这方面的任何文档吗?在他们的网站上找不到任何东西,我见过的大多数其他地方都只是说它是用来更新订阅者的变化
  • 1. '.done' 是异步的,将在 'valueHasMutated()' 调用之后运行,如果你将它放在 done 函数中,它将运行(但每个选项都会调用它)。一种选择是仅在 foreach 中的最后一个选项时执行“valueHasMutated()”。 2.为什么你在复选框上使用点击事件而不是选中?你可以这样去 self.Answers.subscribe((options) => {}) ..

标签: javascript data-binding knockout.js


【解决方案1】:

我被告知问题正在发生,因为 CurrentAnswers() 中对象的属性也无法观察到。由于数组本身没有变化,淘汰赛没有记录它必须重新绑定任何东西,这就是为什么调用 valueHasMutated() 没有改变任何东西,因为数组在 CheckItems() 之前和之后看起来完全相同数组的观点(也是为什么用数组的副本更新不起作用,同样的问题)。将 CurrentAnswers() 设置为空白数组 (self.CurrentAnswers([])),然后将其设置为更新后的值时,由于 KO 识别出实际的数组更改,因此事情发生了正确的变化。

我最终使用的解决方案是利用 ko.mapping.fromJS() 方法用具有可观察属性的对象填充 CurrentAnswers()。在 HTML 和 JS 中进行一些语法更改以正确引用新的 observable 后,一切正常。

【讨论】:

    猜你喜欢
    • 2012-06-26
    • 1970-01-01
    • 1970-01-01
    • 2013-08-30
    • 1970-01-01
    • 2014-05-27
    • 2014-09-21
    • 2011-05-21
    • 1970-01-01
    相关资源
    最近更新 更多