代码之家  ›  专栏  ›  技术社区  ›  Gary McGill

我可以在Knockout中“扩展”这个“值”绑定来进行简单的字符替换吗?

  •  0
  • Gary McGill  · 技术社区  · 6 年前

    我有一个淘汰网站,在那里我可以在各种 input textarea 字段。我想以某种方式连接到“值”绑定中,对用户输入的文本进行一些预处理。(例如,我想用直引号替换“智能引号”)。

    我之所以要这样做,是因为我最终要将此文本存储在一个Oracle数据库中,该数据库的字符集是一个8位字符集(我无法更改)。因此,当文本存储在数据库中时,用户键入的任何无法转换为该字符集的Unicode字符都将被“揓”字符替换。

    最常见的实例是智能引号(在Word或Outlook粘贴的文本中)和某些符号,如欧元符号。对于其中大多数,有一个可以接受的替代品,我可以轻松使用。

    我的计划是在用户的文本到达数据库之前拦截它,并进行一些简单的替换。我不想把代码分散在我的应用程序中,因为所有的文本都是通过KO绑定来的,所以这似乎是一个很好的中心位置。

    有人这样做吗?有什么指示吗?替代方案?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Gary McGill    6 年前

    嗯,我找到了一些可行的方法——尽管我不相信这是一个可靠的解决方案。

    我实际上更换了 init 内置的方法 value 绑定到每当写入值时都进行字符转换的对象:

    ( 注意:下面的代码是typescript,而不是普通的javascript )

        const originalInit = ko.bindingHandlers.value.init;
    
        ko.bindingHandlers.value.init = (
            element: any,
            valueAccessor: () => any,
            allBindingsAccessor: KnockoutAllBindingsAccessor,
            viewModel: any,
            bindingContext: KnockoutBindingContext
        ): void => {
    
            const wrappedValueAccessor = () => {
                const observable = valueAccessor();
                return ko.computed({
                    read: () => ko.unwrap(observable),
                    write: (newValue) => { observable(to8Bit(newValue)); }
                });
            };
    
            originalInit(element, wrappedValueAccessor, allBindingsAccessor, viewModel, bindingContext);
        };
    

    ( to8Bit 是执行字符替换的函数)。

    改变主意…:-)

        2
  •  1
  •   MKougiouris    6 年前

    您可以创建一个自定义绑定处理程序,该处理程序将围绕knockout的绑定处理程序进行封装,并可以在其中添加自定义逻辑。

    例如:

    ko.bindingHandlers.customValueHandler= {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    
    // setup what happens when the binding initializes
    // my custom logic here    
    
    
    // call knockouts value bind init
    ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
    
    },
        update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    
    // setup what happens when the observable update
    // my custom logic here   
    
    // you can then call knockouts update part of default handler
            ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
        }
    }
    

    通过这种方式,您可以使用原始“value”、“text”或任何其他敲除内置绑定的默认功能,同时还可以围绕它包装您自己的自定义逻辑。 这当然意味着您必须将数据绑定重新写入新的自定义处理程序。