2013-05-01 56 views
12

我在我的挖空視圖模型中有一個可觀察的名稱字段。 現在我想限制這個字段中的字符數量,如果它超過了某個數字。Knockout:限制可觀察字段中的字符數

彷彿名稱=「約翰·史密斯」和我有6個字符的限制則
顯示「約翰小號......」

回答

18

另一種可重複使用的解決方案是創建一個顯示文本的修剪版本的自定義綁定。

這可以使底層值保持不受影響,但爲顯示目的修剪文本。這對於消息預覽或將數據擬合到網格列等內容非常有用。

實例綁定:

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 
     }; 
    } 
}; 

使用方法如下:

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

或...

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

See Fiddle

+1

我喜歡這個解決方案;我只是希望建議將未修剪的文本放入元素的標題中以提供原始值的快速預覽;像「element.title = untrimmedText;」如果untrimmedText長度大於maxLength。 – CaNNaDaRk 2013-06-28 15:35:58

+1

只是一個小的評論 - 檢查無刺激的文本的長度超過(trimTextLenth + 3)是個好主意,因爲如果trimTextLenth等於5,但文本是「123456」,結果將是「12345 ...」,這是比未修剪版本更長。 – 2014-01-13 10:13:18

+0

我在這個小提琴中使用了約瑟夫的答案和伊萬的評論:http://jsfiddle.net/8ypdX/90/。這會創建一個名爲truncateText的變量,它允許您定義用於截斷的文本,並測量該變量的長度。 如果修剪後的文本加上截斷文本超過原始字符串,則不執行修剪。 – RussAwesome 2017-03-22 12:34:02

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

或者你可以在你的視圖模型創建一個計算觀察到的,這樣的如:

var self = this; 

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

然後:

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

感謝克里斯.. 它爲我..我 – xyz 2013-05-01 12:10:03

+0

第一'''ñ後,認爲在你的第一個例子中,你錯過了() ame''',如下所示:'' 6? name()。substring(0,5)+'...':name)「>''' – f055 2014-06-11 15:50:27

+1

在Knockout中,您可以使用.length而不必使用()來評估表達式。 – 2014-06-17 14:18:00

7

克里斯迪克森如果您有一個字段具有最大長度,則解決方案非常完美。但是如果你不得不多次重複這個操作,那就變得很麻煩。這時候,你應該寫一個自定義的可觀察的擴展,這樣的:

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; 
}; 

然後,您可以使用它在任何可觀察到的,你可以對任何一個國家指定不同的最大長度。這消除了HTML中的混亂(解決方案1),並且需要編寫計算的可觀察數據(解決方案2)。您只需定義你觀察的方式如下:

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

需要說明的是,在寫入(設置)observable時,這會截斷超過maxLength的任何值,是否正確? – 2013-05-01 14:02:29

+0

@JosephGabriel正好。 – Jalayn 2013-05-01 14:03:17

+0

該解決方案不會限制輸入中可見的字符。 – jmathew 2015-11-16 15:59:23

2

如果要截斷的值數字i NPUT你可以使用和擴展,將截斷值如下所示:

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應用的最大長度綁定,如下所示:

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

我很確定'valueAccessor()'將返回'maxLength'屬性的值,而不是您綁定到元素的可觀察值的值。 – jmathew 2015-11-16 16:04:41

+0

@jmathew希望它現在與編輯更有意義,我添加了綁定的HTML。 – 2015-11-16 16:15:38

+0

valueAccessor - 您可以調用以獲取此綁定中涉及的當前模型屬性的JavaScript函數。在不傳遞任何參數的情況下調用它(即,調用valueAccessor())以獲取當前的模型屬性值。要輕鬆接受可觀測值和普通值,請在返回的值上調用ko.unwrap。 – 2015-11-16 16:15:57