Javascript 淘汰:限制可观察字段中的字符数
我的淘汰视图模型中有一个可观察的名称字段。 现在我想限制这个字段中的字符数,如果它超过某个数字 好像name=“john smith”和我有6个字符的限制,那么Javascript 淘汰:限制可观察字段中的字符数,javascript,html,knockout.js,Javascript,Html,Knockout.js,我的淘汰视图模型中有一个可观察的名称字段。 现在我想限制这个字段中的字符数,如果它超过某个数字 好像name=“john smith”和我有6个字符的限制,那么 显示“john s…” 然后: <span data-bind="text: shortName"></span> 如果有一个字段具有最大长度,则Chris Dixon的解决方案是完美的。但是,如果您必须多次重复此操作,则会变得很麻烦。这时您应该编写一个定制的可观察扩展程序,如下所示: ko.extenders
显示“john s…” 然后:
<span data-bind="text: shortName"></span>
如果有一个字段具有最大长度,则Chris Dixon的解决方案是完美的。但是,如果您必须多次重复此操作,则会变得很麻烦。这时您应该编写一个定制的可观察扩展程序,如下所示:
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;
};
<div data-bind="trimText: myText1"></div>
然后,您可以在任何可观察对象上使用它,并且可以为其中任何一个对象指定不同的最大长度。这消除了HTML中的混乱(解决方案1),以及编写计算的可观察对象(解决方案2)的必要性。您只需通过以下方式定义您的可观察对象:
this.shortName = ko.observable().extend({ maxLength: 25 });
另一个可重用的解决方案是创建一个自定义绑定,以显示文本的修剪版本 这允许基础值不受影响,但出于显示目的修剪文本。这对于消息预览或将数据拟合到网格列中非常有用 绑定示例:
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
};
}
};
ko.bindingHandlers.trimLengthText={};
ko.bindingHandlers.trimText={
init:函数(元素、valueAccessor、allBindingsAccessor、viewModel){
var trimmedText=ko.computed(函数(){
var untrimmedText=ko.utils.unwrapObservable(valueAccessor());
var defaultMaxLength=20;
var minLength=5;
var maxLength=ko.utils.unwrapObservable(allBindingsAccessor().trimTextLength)| | defaultMaxLength;
如果(maxLengthmaxLength?untrimmedText.substring(0,maxLength-1)+’…':untrimmedText;
返回文本;
});
ko.applyBindingsToNode(元素{
文本:trimmedText
},视图模型);
返回{
ControlsDescentBindings:true
};
}
};
像这样使用它:
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;
};
<div data-bind="trimText: myText1"></div>
或者
如果要截断数值输入的值,可以使用和extender来截断该值,如下所示:
ko.extenders.truncateValue = function(target, option) {
target.subscribe(function (newValue) {
if(newValue.length > option){
target(newValue.substring(0,option));
}
});
return target;
};
然后创建一个自定义绑定,将扩展程序附加到可观察对象:
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);
}
};
在html上应用maxLength绑定,如下所示:
<input type="number" data-bind="maxLength: yourObservable" maxlength="9"></input>
需要澄清的是,在写入(设置)可观察对象时,这将截断任何超过maxLength的值,对吗?此解决方案不限制输入中可见的字符。我发现了一个限制可见字符的版本。我喜欢此解决方案;我只是想建议将未经修剪的文本放入元素的标题中,以提供原始值的快速预览;类似于“element.title=untrimmetext;”的内容,如果untrimmetext长度大于maxLength。只需一个小注释-最好检查untimmed文本的长度是否大于(trimmetextlenth+3),因为如果trimmetextlenth等于5,但文本是“123456”,结果将是“12345…”,这比未修剪的版本要长。我在这把小提琴中使用了约瑟夫的答案和伊凡的评论:。这将创建一个名为truncateText的变量,该变量允许您定义用于截断的文本,并测量该变量的长度。如果修剪后的文本加上截断文本大于原始字符串,则不会执行修剪。我认为在您的第一个示例中,您在第一个名称
之后遗漏了(),如:
在Knockout中,您可以使用.length,而不必使用()计算表达式。我非常确定'valueAccessor()'将返回'maxLength'属性的值,而不是绑定到元素的可观察值。@jmathew希望现在通过编辑变得更有意义,我添加了带有binding.valueAccessor的html-一个JavaScript函数,您可以调用它来获取此绑定中涉及的当前模型属性。调用此函数而不传递任何参数(即调用valueAccessor())以获取当前模型属性值。要轻松接受可观察值和普通值,请对返回的值调用ko.unwrap。啊,我明白了,我认为您的html应该看起来像data bind=“value:yourObservable,maxLength:9”。我的错误。
<input type="number" data-bind="maxLength: yourObservable" maxlength="9"></input>