Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Knockout.js 使用自定义绑定设置剔除值的格式_Knockout.js - Fatal编程技术网

Knockout.js 使用自定义绑定设置剔除值的格式

Knockout.js 使用自定义绑定设置剔除值的格式,knockout.js,Knockout.js,我想对绑定到HTML输入元素的敲除对象执行双向转换。更具体地说,我希望在复制到输入时将字符串替换为\n个字符,并在复制回模型时将\n个字符替换为字符串。换言之,我有以下两个要求: 当值从knockout observable复制时,它应该经过一次转换。 当输入中的值发生变化并复制回敲除可观测值时,应进行反向转换。 因为我使用的是knockout.mapping,所以我不想使用.extend,而是使用自定义bindingHandler 我发现了很多例子,在这些例子中,你可以将一个可观察的元素格式化

我想对绑定到HTML输入元素的敲除对象执行双向转换。更具体地说,我希望在复制到输入时将字符串替换为\n个字符,并在复制回模型时将\n个字符替换为字符串。换言之,我有以下两个要求:

当值从knockout observable复制时,它应该经过一次转换。 当输入中的值发生变化并复制回敲除可观测值时,应进行反向转换。 因为我使用的是knockout.mapping,所以我不想使用.extend,而是使用自定义bindingHandler

我发现了很多例子,在这些例子中,你可以将一个可观察的元素格式化成一个只读元素,比如DIV。 我还发现了很多其他的例子,你可以修改输入的值。 但这些都不适合我。我尝试过的每件事都会导致转换以一种或另一种方式工作,但不是两种方式都成功

以下是我最近的一次尝试:

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(/&gt;/g, '>')
                    .replace(/&lt;/g, '<')
                    .replace(/&#39;/g, "'")
                    .replace(/&quot;/g, '"')
                    .replace(/&amp;/g, '&');
                return textValue;
            },
            write: function (value) {
                var valueObservable = valueAccessor();
                var htmlValue = String(value)
                    .replace(/&/g, '&amp;')
                    .replace(/"/g, '&quot;')
                    .replace(/'/g, '&#39;')
                    .replace(/</g, '&lt;')
                    .replace(/>/g, '&gt;')
                    .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(/&gt;/gi, '>')
                    .replace(/&lt;/gi, '<')
                    .replace(/&#39;/gi, "'")
                    .replace(/&quot;/gi, '"')
                    .replace(/&amp;/gi, '&');
                return textValue;
            },
            write: function (value) {
                var valueObservable = valueAccessor();
                var htmlValue = String(value)
                    .replace(/&/gi, '&amp;')
                    .replace(/"/gi, '&quot;')
                    .replace(/'/gi, '&#39;')
                    .replace(/</gi, '&lt;')
                    .replace(/>/gi, '&gt;')
                    .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很高兴听到你解决了这个问题!你能补充一些解决方案的细节作为回答吗?也许其他人也遇到了类似的问题,他们可能会在你的答案中找到用处。