我在KO中有两个同级输入foreach
:
<input type="text" name="background_color" data-bind="value: $data.background_color">
<input type="hidden" name="background_color" data-bind="value: $data.background_color">
生成的DOM如下所示:
<input type="text" name="background_color" data-bind="value: $data.background_color">
<input type="hidden" name="background_color" data-bind="value: $data.background_color" value="#c9311b">
我是通过jQuery的html
函数,然后在其他地方使用HTML来获取的,但是当我在其他地方使用它时,文本输入的值未设置。
我的解决方法是改用attr
绑定,这有效
data-bind="attr: {'value':$data.background_color}"
但这很痛苦。为什么只为该值设置input[type="hidden"]
?
使用KO v3.3.0。
文本输入的当前值根本不会在元素/属性级别的DOM中反映出来,因此innerHTML
jQueryhtml()
不会看到它。
下面的解决方案,但首先让我们看一下它的行为value
以及为什么它type="text"
与vs.有所不同type="hidden"
。
value
属性与value
属性该value
属性不是文本输入的值,而是文本输入的默认值。设置文本输入的值不会设置属性。相反,对于隐藏的输入而言,在“默认值”和“当前值”之间进行区分是没有意义的,因此设置value
属性确实会设置属性,因此你会在生成的HTML中看到该属性。
的这种行为value
与KO无关,它仅在原始DOM操作中发生:
document.getElementById("the-text-field").value = "text field value";
document.getElementById("the-hidden-field").value = "hidden field value";
<input id="the-text-field" type="text" name="background_color" >
<input id="the-hidden-field" type="hidden" name="background_color">
HTML5规范在此讨论了这一点,其中讨论了该value
属性及其所具有的不同模式:
该
value
IDL属性允许脚本操作的输入元素的值。该属性采用以下方式之一,以定义其行为:价值
获取时,它必须返回该元素的当前值。设置时,必须将元素的值设置为新值,将元素的脏值标志设置为true,如果元素的type属性的当前状态定义为1,则调用值清除算法,然后,如果元素具有文本输入光标位置,应将文本输入光标的位置移至文本字段的末尾,取消选择任何选定的文本并将选择方向重置为无。
默认
获取时,如果元素具有value属性,则必须返回该属性的值;否则,返回false。否则,它必须返回空字符串。设置时,必须将元素的value属性设置为新值。
... (还有其他两种模式)
...在这里,它说input type="hidden"
的value
使用“默认”模式,但是input type="text"
使用“值”模式(你必须向下滚动到“ IDL属性和方法”表;这value
是列出的第三个表)。
如你所见,解决方案是确保value
设置了属性。如你所提到的,你可以使用attr
绑定来做到这一点,但是正如你所说的那样,这有点痛苦。相反,你可以给自己一个自定义绑定,该绑定既可以设置值也可以设置默认值。由于默认值作为value
属性反映在DOM中,因此你会在html()
以下代码中看到它:
// The binding handler
ko.bindingHandlers.valueWithAttr = {
update: function(element, valueAccessor) {
element.value = element.defaultValue = ko.unwrap(valueAccessor());
// Or we could do:
// var value = ko.unwrap(valueAccessor());
// element.value = value;
// element.setAttribute("value", value);
// ...but since that's what setting `defaultValue` does...
}
};
// Using it
var vm = {
background_color: "blue"
};
ko.applyBindings(vm, document.body);
$("<pre>").text(
"html of the inputs: " +
$("#container").html()
).appendTo(document.body);
<div id="container">
<input type="text" name="background_color" data-bind="valueWithAttr: $data.background_color">
<input type="hidden" name="background_color" data-bind="valueWithAttr: $data.background_color">
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
非常好的解释,这使我注意到了我的问题,实际上是如果我使用jquery的.html()复制内容并将其粘贴到其他地方,则只有在设置了value属性的情况下,视觉上才会显示的值,这时我将这是一个答案,因为这是一个非常好的答案,不幸的是我必须继续我的血腥修复
@johnSmith:很高兴,我学到了一些东西(我不知道
value
在隐藏的输入中设置属性会设置它们的属性,直到我看到您的问题并尝试了它,这使我开始研究规范)。出于好奇,我回来检查了这个问题。尽管起初我可能不知道OP使用淘汰赛的方式,但事实证明这确实很有趣,而且我也学到了一些新知识。