[英]KnockoutJS: Writable computed observable not updating
我在以下代码中尝试使用可写的可计算可观察值来验证用户输入,并自动拒绝无效输入。 这只是一些测试代码,我试图阻止用户从文本中删除逗号。 如果用户删除了逗号字符,我试图将编辑器重新绑定到先前的值以覆盖最新的更改。 使用可写的计算字段是否可能? 我遇到的问题是,仅当我加载页面时(手动设置ValidText属性之后),可写的计算绑定才会启动。但是,当用户在编辑器中键入内容时,我无法启动它。
码:
<script type="text/javascript">
var model = null;
function EditModel() {
this.Count = 2;
var self = this;
this.ExistingValue = ko.observable("");
this.ValidText = ko.computed({
read: function () {
return self.ExistingValue();
},
write: function (text) {
if (text.split(',').length === self.Count) {
self.ExistingValue(text);
}
},
owner: self
});
}
$(document).ready(function () {
model = new EditModel();
model.ValidText('@(Model.Text)');
ko.applyBindings(model);
});
</script>
<div id="mainContainer">
<div id="editor" contenteditable="true" class="commentEditBox" data-bind="text: ValidText, valueUpdate: 'afterkeydown'" ></div>
</div>
最终有了自定义绑定的想法,并将代码转换为以下代码:
<script type="text/javascript">
var model = null;
ko.bindingHandlers.customEditorBinding = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
$(element).on('keydown', function () {
var observable = valueAccessor();
observable($(this).text());
});
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var text = ko.utils.unwrapObservable(valueAccessor());
if (text.split(',').length === model.Count) {
model.ValidText(text);
model.PreviousText = text;
$(element).text(text);
}
else {
model.ValidText(model.PreviousText);
$(element).text(model.PreviousText);
}
}
};
function EditModel() {
var self = this;
self.Count = 2;
self.ValidText = ko.observable("");
self.PreviousText = null;
}
$(document).ready(function () {
model = new EditModel();
model.ValidText('This is,a test');
ko.applyBindings(model);
});
</script>
<div id="mainContainer">
<div id="editor" contenteditable="true" class="commentEditBox" data-bind="customEditorBinding:ValidText" ></div>
</div>
好的,混淆使用self和其他方法,您已经将其绑定到使用文本的div上,并且试图使它在值更改时进行更新。 该html元素没有任何值,因此这就是为什么它不触发。
看一下自定义绑定,并将您的写入逻辑移到它的更新方法中。
ko.bindingHandlers.yourBindingName = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
// This will be called when the binding is first applied to an element
// Set up any initial state, event handlers, etc. here
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
// This will be called once when the binding is first applied to an element,
// and again whenever the associated observable changes value.
// Update the DOM element based on the supplied values here.
}
};
在您的write方法中,添加以下else子句:
else { self.ValidText.notifySubscribers(self.ExistingValue()); }
这将强制文本框更新回原始值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.