Html Knockout:限制可观察字段中的字符数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16317622/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 08:03:24  来源:igfitidea点击:

Knockout : limit number of characters in an observable field

javascripthtmlknockout.js

提问by xyz

I have an observable name field in my knockout view model. Now i want to limit the number of characters in this field if it exceeds certain number.

我的淘汰赛视图模型中有一个可观察的名称字段。现在我想限制这个字段中的字符数,如果它超过一定数量。

As if name = "john smith" and i have a limit of 6 characters then
display " john s... "

好像 name = "john smith" 并且我有 6 个字符的限制然后
显示 "john s... "

回答by Joseph Gabriel

Another reusable solution is to create a custom binding that displays a trimmed version of the text.

另一个可重用的解决方案是创建一个自定义绑定来显示文本的修剪版本。

This allows the underlying value to remain unaffected, but trims the text for display purposes. This would be useful for something like a message preview, or for fitting data into a grid column.

这允许基础值保持不受影响,但为了显示目的而修剪文本。这对于消息预览或将数据拟合到网格列中非常有用。

Example binding:

示例绑定:

ko.bindingHandlers.trimLengthText = {};
ko.bindingHandlers.trimText = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var trimmedText = ko.computed(function () {
            var untrimmedText = ko.utils.unwrapObservable(valueAccessor());
            var defaultMaxLength = 20;
            var minLength = 5;
            var maxLength = ko.utils.unwrapObservable(allBindingsAccessor().trimTextLength) || defaultMaxLength;
            if (maxLength < minLength) maxLength = minLength;
            var text = untrimmedText.length > maxLength ? untrimmedText.substring(0, maxLength - 1) + '...' : untrimmedText;
            return text;
        });
        ko.applyBindingsToNode(element, {
            text: trimmedText
        }, viewModel);

        return {
            controlsDescendantBindings: true
        };
    }
};

Use it like this:

像这样使用它:

<div data-bind="trimText: myText1"></div>

or...

或者...

<div data-bind="trimText: myText1, trimTextLength: 10"></div>

See Fiddle

见小提琴

回答by Chris Dixon

<span data-bind="text: (name.length > 6 ? name().substring(0, 5) + '...' : name)"></span>

Or you can create a computed observable in your ViewModel, such as:

或者你可以在你的 ViewModel 中创建一个计算的 observable,例如:

var self = this;

this.shortName = ko.computed(function() {
   return (self.name.length > 6 ? self.name().substring(0, 5) + '...' : self.name);
});

and then:

进而:

<span data-bind="text: shortName"></span>

回答by Jalayn

Chris Dixon's solutions are perfect if you have one field that has a max length. But if you have to repeat this operation multiple times it becomes cumbersome. That is when you should write a custom observable extender, like this:

如果您有一个具有最大长度的字段,那么 Chris Dixon 的解决方案是完美的。但是如果你必须多次重复这个操作,它就会变得很麻烦。那就是你应该编写自定义 observable 扩展器的时候,如下所示:

ko.extenders.maxLength = function(target, maxLength) {
    //create a writeable computed observable to intercept writes to our observable
    var result = ko.computed({
        read: target,  //always return the original observables value
        write: function(newValue) {
            var current = target(),
                valueToWrite = newValue ? newValue.substring(0, Math.min(newValue.length, maxLength)) : null;

            //only write if it changed
            if (valueToWrite !== current) {
                target(valueToWrite);
            } else {
                //if the rounded value is the same, but a different value was written, force a notification for the current field
                if (newValue !== current) {
                    target.notifySubscribers(valueToWrite);
                }
            }
        }
    });

    //initialize with current value to make sure it is rounded appropriately
    result(target());

    //return the new computed observable
    return result;
};

You can then use it on any observable, and you can specify a different maximum length for any of them. This removes the clutter from the HTML (solution 1), and the necessity to write a computed observable (solution 2). You simply define your observable the following way:

然后你可以在任何 observable 上使用它,你可以为它们中的任何一个指定不同的最大长度。这消除了 HTML 中的混乱(解决方案 1),以及编写计算 observable(解决方案 2)的必要性。您只需通过以下方式定义您的可观察对象:

this.shortName = ko.observable().extend({ maxLength: 25 });

回答by LUIS PEREIRA

If you want to truncate the value for a numeric input you could use and extender that will truncate the value like the following:

如果你想截断数字输入的值,你可以使用和扩展器来截断值,如下所示:

ko.extenders.truncateValue = function(target, option) {                            
        target.subscribe(function (newValue) {
            if(newValue.length > option){
                target(newValue.substring(0,option));
            }                    
        });

        return target;
    };

And then create a custom binding that will will append the extender to the observable:

然后创建一个自定义绑定,将扩展器附加到可观察对象:

ko.bindingHandlers.maxLength = {
    init:  function (element, valueAccessor, allBindingsAccessor, viewModel) {
        'use strict';                     

        var maxlength = element.getAttribute("maxlength");

        valueAccessor().extend({truncateValue: maxlength })
        ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor, viewModel);    
    }   
};

On your html you apply the maxLength binding as follows:

在您的 html 上,您应用 maxLength 绑定如下:

<input type="number" data-bind="maxLength: yourObservable" maxlength="9"></input>