(这是this question)
的后续行动在Knockout.js中,textInput绑定在每次击键后更新模型,并允许我实现一个简单的输入掩码。它本身很好用,但是当输入字段在模板中时,每次击键后该字段都会失去焦点。
这个小提琴演示了这个问题。请注意,我需要一些$ parent trickery来使输入字段在两个方向上工作(读取和写入)。如果我使用$ data,它会在外部更新时读取新值,但不会将其写入模型并且不应用输入掩码。
https://jsfiddle.net/h0qh3ecc/4/
简化代码如下:
HTML:
textInput (this one works):<br>
<input data-bind="textInput: formattedString" >
<div data-bind="text: formattedString"></div>
<hr>
template textInput ($parent loses focus / $data doesn't call write):<br>
<script type="text/html" id="input-standalone-template">
<input data-bind="textInput: $parent.formattedString"> <input data-bind="textInput: $data">
</script>
<div data-bind="template: { name: 'input-standalone-template', data: formattedString }"></div>
<hr>
JavaScript的:
var model = (function () {
function format(str) {
var undone = str.replace(/-/g, '');
if (undone.length > 3) {
undone = undone.substr(0,3) + '-' + undone.substr(3);
}
return undone;
}
var displayString = ko.observable('');
var formattedString = ko.computed({
read: function () {
return displayString();
},
write: function (newValue) {
var f = format(newValue);
console.debug("Format", newValue, "=", f);
displayString(f);
}
});
return {
formattedString: formattedString
};
}());
ko.applyBindings(model)
这是一个错误吗?有解决方法吗?
答案 0 :(得分:0)
我刚刚找到了一种解决方法:我必须将$data
(或$parent
,具体取决于页面结构)而不是字段直接传递给模板data
参数。必须相应地调整模板。
例如,而不是
<!-- define template -->
<script type="text/html" id="my-input-template">
<input data-bind="textInput: $data">
</script>
<!-- call template (passing field, causes focus issues) -->
<div data-bind="template: {
name: 'my-input-template',
data: formattedString
}">
</div>
我应该做
<!-- define template -->
<script type="text/html" id="my-input-template">
<input data-bind="textInput: formattedString">
</script>
<!-- call template (passing $data, works fine) -->
<div data-bind="template: {
name: 'my-input-template',
data: $data
}">
</div>
由于某些不明原因,此更改解决了问题。