【问题标题】:How To Change Text For Selected Fields To Uppercase Using KnockoutJS?如何使用 KnockoutJS 将选定字段的文本更改为大写?
【发布时间】:2020-05-11 16:09:13
【问题描述】:

我的应用程序所有者希望选择文本字段为大写,就像打开大写锁定一样。我正在为这些字段使用带有 observables 的 KnockoutJS 视图模型。有没有一种方法可以有效地将任何用户输入的文本转换为大写?

我在想要更改的控件上放置了一个input 事件,但发现虽然它有效,但可观察对象并未更新。

<input type="text" maxlength="80" data-bind="value: colorName, disable: $parent.isReadOnly, event: { 'input': toUpper }" />

toUpper: function (d, e) {
    if (e.target) {
        if (e.target.value) {
            e.target.value = e.target.value.toUpperCase();
        }
    }
}

我也一直在考虑将ucase CSS 类放在我想要大写的控件上,然后放在客户端或服务器上,将这些字段保存为大写。

.ucase {
    text-transform: uppercase;
}

【问题讨论】:

    标签: javascript knockout.js


    【解决方案1】:

    你可以扩展你的 observables -

    <input data-bind="value: colorName, valueUpdate:'afterkeydown'" />
    
    ko.extenders.uppercase = function(target, option) {
        target.subscribe(function(newValue) {
           target(newValue.toUpperCase());
        });
        return target;
    };
    
    var colorName = ko.observable().extend({ uppercase: true });
    

    小提琴示例 - http://jsfiddle.net/kbFwK/

    基本上,只要值发生变化,它就会将 observable 的值转换为大写。

    这里的缺点是它实际上会更改值并且也会以这种方式存储它。您总是可以将计算属性附加到可观察对象上,仅用于显示目的。您可以使用 ko.computed、自定义绑定处理程序(因为它仅用于演示)或类似的东西来做到这一点。如果您正在寻找更多内容,请在评论中告诉我。

    编辑

    使用 afterkeydown 更新 - http://jsfiddle.net/kbFwK/2/

    【讨论】:

    • 当用户输入时,我需要将输入大写,就像打开大写锁定键一样。我在最初的帖子中忽略了这一点。我已经更新了我的问题。不过这是个好主意。
    • 您需要做的就是让它在按键按下时发出通知。我将它添加到我的小提琴中。
    • 我喜欢使用扩展器。感谢您的帮助!
    • 在将文本插入现有字符串时,有没有办法保留光标位置?
    • 好问题,我不确定。我会用 JavaScript / Knockout 标签打开一个新问题,以找出并获得更多曝光。
    【解决方案2】:

    这是我编写的一个自定义绑定,它确保输入字段和 observable 都是大写的。它应该像 textInput 绑定一样工作。

    ko.bindingHandlers.textInputUpperCase = {
        init: (element, valueAccessor) => {
            const observable = valueAccessor();
            let preventDoubleUpdate = false;
    
            function update(newValue) {
                if (preventDoubleUpdate) {
                    preventDoubleUpdate = false;
                } else {
                    switch(typeof newValue) {
                        //Undefined value will be displayed as empty in the input field.
                        case 'undefined':
                            element.value = '';
                            break;
                        //String value will be converted to upper case.
                        case 'string':
                            const upperCase = newValue.toLocaleUpperCase();
                            //Check if input field matches the observable. If not the change was made directly to the observable.
                            const match = element.value.toLocaleUpperCase() === upperCase;
                            //Remember the cursor position.
                            const selectionStart = element.selectionStart;
                            const selectionEnd = element.selectionEnd;
                            //Update the input text (will move the cursor to the end of the text).
                            element.value = upperCase;
                            //Move the cursor to it's original position if the change came from the input field.
                            if (match) {
                                element.selectionStart = selectionStart;
                                element.selectionEnd = selectionEnd;
                            }
                            //Update the observable if necessary and make sure it won't do a double update.
                            if (newValue !== upperCase) {
                                preventDoubleUpdate = true;
                                observable(upperCase);
                            }
                            break;
                        default:
                            element.value = newValue;
                    }
                }
            }
    
            //Run the update function each time the observable has been changed
            observable.subscribe(update);
    
            //Initiate the observable and input
            update(observable());
    
            //Update the observable on changes of the text in the input field
            element.addEventListener('input', event => {
                observable(event.target.value);
            });
        }
    };
    

    一个小警告。如果您写入 observable,它将通知其他订阅者两次。首先是你写它的时候,然后是大写的时候。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多