Knockout.js 使用自定义绑定设置剔除值的格式
我想对绑定到HTML输入元素的敲除对象执行双向转换。更具体地说,我希望在复制到输入时将字符串替换为\n个字符,并在复制回模型时将\n个字符替换为字符串。换言之,我有以下两个要求: 当值从knockout observable复制时,它应该经过一次转换。 当输入中的值发生变化并复制回敲除可观测值时,应进行反向转换。 因为我使用的是knockout.mapping,所以我不想使用.extend,而是使用自定义bindingHandler 我发现了很多例子,在这些例子中,你可以将一个可观察的元素格式化成一个只读元素,比如DIV。 我还发现了很多其他的例子,你可以修改输入的值。 但这些都不适合我。我尝试过的每件事都会导致转换以一种或另一种方式工作,但不是两种方式都成功 以下是我最近的一次尝试:Knockout.js 使用自定义绑定设置剔除值的格式,knockout.js,Knockout.js,我想对绑定到HTML输入元素的敲除对象执行双向转换。更具体地说,我希望在复制到输入时将字符串替换为\n个字符,并在复制回模型时将\n个字符替换为字符串。换言之,我有以下两个要求: 当值从knockout observable复制时,它应该经过一次转换。 当输入中的值发生变化并复制回敲除可观测值时,应进行反向转换。 因为我使用的是knockout.mapping,所以我不想使用.extend,而是使用自定义bindingHandler 我发现了很多例子,在这些例子中,你可以将一个可观察的元素格式化
ko.bindingHandlers.htmlToTextValue = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, context) {
var interceptor = ko.computed({
read: function () {
var valueObservable = valueAccessor();
var value = valueObservable();
var textValue = String(value)
.replace(/\<br\>/g, "\n")
.replace(/>/g, '>')
.replace(/</g, '<')
.replace(/'/g, "'")
.replace(/"/g, '"')
.replace(/&/g, '&');
return textValue;
},
write: function (value) {
var valueObservable = valueAccessor();
var htmlValue = String(value)
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/\n/g, "<br>");
valueObservable(htmlValue);
}
,disposeWhenNodeIsRemoved: element
});
ko.applyBindingsToNode(element, { value: interceptor }, context);
}
};
以下是它的用途:
<input type="textarea" data-bind="htmlToTextValue: Value" />
它不起作用,因为您只设置了init函数,所以它不会响应任何更新。尝试将更新选项添加到处理程序中
ko.bindingHandlers.htmlToTextValue = {
init: function(element, valueAccessor) {
// your code
},
update: function(element, valueAccessor) {
// your code
}
}
以下是文本和HTML之间双向绑定的有效解决方案:
ko.bindingHandlers.htmlToTextValue = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, context) {
var interceptor = ko.computed({
read: function () {
var valueObservable = valueAccessor();
var value = valueObservable();
var textValue = String(value)
.replace(/<br>/gi, "\n")
.replace(/>/gi, '>')
.replace(/</gi, '<')
.replace(/'/gi, "'")
.replace(/"/gi, '"')
.replace(/&/gi, '&');
return textValue;
},
write: function (value) {
var valueObservable = valueAccessor();
var htmlValue = String(value)
.replace(/&/gi, '&')
.replace(/"/gi, '"')
.replace(/'/gi, ''')
.replace(/</gi, '<')
.replace(/>/gi, '>')
.replace(/\n/gi, "<br>");
valueObservable(htmlValue);
}
});
ko.applyBindingsToNode(element, { value: interceptor }, context);
}
};
你是说我也应该将init代码复制到update方法吗?这似乎不太正确,因为我调用了ko.applybindingstoode.init,本质上,它允许您绑定来自可观察对象的值,而更新允许您将元素中的值映射回可观察对象/值。我这样做是为了找约会对象。init和update是可选的,具体取决于您想要的是单向绑定还是双向绑定。我有一些只使用init,一些使用更新,还有一些同时使用两者。@JoshMouch您不应该从中调用applyBindings,而应该更新元素节点内容。下面是一个示例:您可以尝试在jsfiddle/jsbin中创建一个小演示吗?你也试过textarea吗?因此,我认为你在寻找这样的东西,虽然时间已经晚了,我似乎不明白为什么没有显示初始状态。在文本区域中键入以查看工作情况…@Jeroen您的示例非常有效,但在我自己的代码中不起作用。我运行的是淘汰版3.1.0,而JSFIDLE运行的是3.0.0。我读到更新版本的knockout忽略了对ko.bindingHandlers.value.init的调用。我不知道这是不是真的,或者这就是为什么。@Jeroen:事实上,看起来MVC控件工具包在我的文本区域中插入了一个额外的绑定,这才是真正的问题。谢谢你的帮助@JoshMouch很高兴听到你解决了这个问题!你能补充一些解决方案的细节作为回答吗?也许其他人也遇到了类似的问题,他们可能会在你的答案中找到用处。