Javascript selectbox页面加载时取消订阅触发器

Javascript selectbox页面加载时取消订阅触发器,javascript,knockout.js,Javascript,Knockout.js,我使用subscribe创建了一个扩展程序,目的是拦截用户对输入字段的更改并强制设置一个值 例如,我在可观察对象上设置了一个强制值“Bar”。如果用户将其更改为“Foo”,我将强制其更改为“Bar”,并通知用户。 (用于原型/示例解决方案) 它适用于文本框和单选按钮,但不适用于选择框。它似乎是在页面加载时触发的,而不仅仅是在更改时 小提琴: 当您运行它时,尽管值没有改变,选择框扩展程序仍会被触发。值属性是一个字符串,因此敲除将尝试将值[“1”、“2”、“3”]与您的可观察对象相匹配,其中包含数字

我使用subscribe创建了一个扩展程序,目的是拦截用户对输入字段的更改并强制设置一个值

例如,我在可观察对象上设置了一个强制值“Bar”。如果用户将其更改为“Foo”,我将强制其更改为“Bar”,并通知用户。 (用于原型/示例解决方案)

它适用于文本框和单选按钮,但不适用于选择框。它似乎是在页面加载时触发的,而不仅仅是在更改时

小提琴:


当您运行它时,尽管值没有改变,选择框扩展程序仍会被触发。

值属性是一个
字符串,因此敲除将尝试将值
[“1”、“2”、“3”]
与您的可观察对象相匹配,其中包含数字
1
2
。它看不到选定的值,因此它会将您的可观测值更新为第一个

要快速解决问题,请将
选择框更改为
ko.observable(“1”)
,将强制值更改为
“2”

与问题无关的其他建议:

您当前的扩展器将始终触发两个订阅更改。一个用于第一次更改,一个用于实际重置。如果将可观测值包装在读/写计算中,则会出现以下情况:

ko.extenders.forcedValue = function(target, forcedValue) {
  return ko.computed({
    read: target.extend({ notify: "always" }),
    write: function(newValue) {
      console.log("Attempt:", target(), "->", newValue);

      if (newValue !== forcedValue) {
        console.log("Using " + forcedValue + " instead."); 
        target(forcedValue);
      } else {
        target(newValue);
      }

    }
  }).extend({ notify: "always" });
};

对我来说,它在小提琴中变化得很好。(FF 51.0.1,Chrome 55.0.2883,IE 11),但是,在页面加载时,所有浏览器中的值都是1,尽管会弹出警报。@Balázs问题在于,警报是在页面加载时触发的。应该只在更改为其他值时弹出。当然!这就是为什么当我使用一个可观察的数组作为选项时它会起作用。非常感谢。是的,谢谢你的建议,我从未真正了解如何使用读/写选项。谢谢你!您的脚本似乎只适用于第一次更改,如果您多次更改该值,它会通过吗?jsfiddle.net/4gus57pd/14或者,如果您重新加载页面,它似乎会保留该值,但在更改后,它看起来不会保留该值。啊,我忘记了另外一个
notify:“always”
extender。发生的情况是,当计算出的“跳过”无效更新时,值从
2
变为
2
。这不会自动触发更新,因此UI将开始落后。需要告知
读取
可观察对象始终共享设置新值的尝试。修正:感谢修正和解释!
ko.extenders.forcedValue = function(target, forcedValue) {
  return ko.computed({
    read: target.extend({ notify: "always" }),
    write: function(newValue) {
      console.log("Attempt:", target(), "->", newValue);

      if (newValue !== forcedValue) {
        console.log("Using " + forcedValue + " instead."); 
        target(forcedValue);
      } else {
        target(newValue);
      }

    }
  }).extend({ notify: "always" });
};