2013-05-01 12 views
12

Mam obserwowalne pole nazwy w moim modelu widoku nokautu. Teraz chcę ograniczyć liczbę znaków w tym polu, jeśli przekracza określoną liczbę.Knockout: limit liczby znaków w obserwowalnym polu

Jakby name = „Jan Kowalski” i mam limit 6 znaków następnie
wyświetlania „jan s ...”

Odpowiedz

18

Innym rozwiązaniem wielokrotnego użytku jest utworzenie niestandardowego powiązania, które wyświetla przyciętą wersję tekstu.

Umożliwia to zachowanie podstawowej wartości, ale powoduje przycięcie tekstu w celu wyświetlenia. Byłoby to przydatne w przypadku podglądu wiadomości lub dopasowania danych do kolumny siatki.

Przykład wiązania:

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

Używaj go tak:

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

lub ...

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

See Fiddle

+1

Podobało mi się to rozwiązanie; Chciałbym tylko zasugerować umieszczenie niepoprawnego tekstu w tytule elementu, aby zapewnić szybki podgląd oryginalnej wartości; coś w stylu "element.title = untrimmedText;" jeśli untrimmedText length jest dłuższy niż maxLength. – CaNNaDaRk

+1

Tylko jeden mały komentarz - dobrze byłoby sprawdzić, czy długość nietekstu jest większa niż (trimTextLenth + 3), ponieważ jeśli trimTextLenth ma wartość 5, ale tekst to "123456", wynikiem będzie "12345 ...", co jest dłuższy niż wersja niezwiązana. –

+0

Użyłem odpowiedzi Josepha i komentarza Iwana w tym skrzypcach: http: //jsfiddle.net/8ypdX/90/. Tworzy to zmienną o nazwie truncateText, która pozwala zdefiniować tekst używany do obcięcia i mierzy długość tej zmiennej. Jeśli przycięty tekst plus tekst skracany jest większy niż oryginalny ciąg, to nie wykonuje przycięcia. – RussAwesome

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

Albo można utworzyć obliczany obserwowalne w ViewModel, takie jako:

var self = this; 

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

a następnie:

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

Thanks Chris .. to działa dla mnie .. – xyz

+0

myślę w pierwszym przykładzie Przegapiłeś() po pierwszej '' 'n ame''' jak w: '' '' '' – f055

+1

W Knockout można użyć. length bez konieczności sprawdzania wyrażenia za pomocą(). –

7

Chris Dixon rozwiązania są idealne, jeśli masz jedno pole, które ma maksymalną długość. Ale jeśli musisz powtórzyć tę operację kilka razy, staje się ona nieporęczna. To jest, gdy trzeba napisać niestandardowy zaobserwowania Extender tak:

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

Następnie można go używać na dowolnym zaobserwować, można określić inną maksymalną długość dla każdego z nich. Usuwa to bałagan z HTML (rozwiązanie 1) i konieczność zapisu obliczonego obserwowalnego (rozwiązanie 2). Po prostu zdefiniuj swoje obserwowalne w następujący sposób:

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

Po prostu, aby być czystym, podczas zapisywania do (ustawienia) obserwowalnego, to obetnie wszelkie wartości, które przekraczają maxLength, prawda? –

+0

@JosephGabriel dokładnie. – Jalayn

+0

To rozwiązanie nie ogranicza znaków widocznych na wejściu. – jmathew

2

Jeśli chcesz obciąć wartości dla numeryczny i nPrzenieś można użyć i przedłużacz że obetnie wartości jak poniżej:

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

     return target; 
    }; 

a następnie utworzyć zwyczaj wiążącego, który woli dołączy przedłużacz do zaobserwowania:

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

Na html zastosowanie MaxLength wiążące się następująco:

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

Jestem prawie pewna, że ​​"valueAccessor()" zwróci wartość właściwości "maxLength", a nie wartość obserwowalnego obiektu związanego z elementem. – jmathew

+0

@jmathew mam nadzieję, że teraz ma sens z edycją, dodałem html z powiązaniem. –

+0

valueAccessor - funkcja JavaScript, którą można wywołać w celu uzyskania bieżącej właściwości modelu, która jest zaangażowana w to powiązanie. Wywołaj to bez przekazywania jakichkolwiek parametrów (tj. Wywołaj valueAccessor()), aby uzyskać bieżącą wartość właściwości modelu. Aby łatwo zaakceptować obie obserwowalne i zwykłe wartości, wywołaj ko.unwrap na zwróconej wartości. –

Powiązane problemy