2012-12-21 8 views
9

Mam 3 obserwowalne zmienne w modelu widoku i chcę wyprowadzać do sformatowanej wartości. Jednak nie chcę pisać metody obliczeniowej dla każdego z nich, ponieważ są one identyczne. Jaki jest najlepszy sposób ponownego użycia kodu? Dzięki.Tworzenie obliczalnego obserwowalnego dla sformatowanych wartości dla wielu zmiennych

Kod mam zamiar osiągnąć to:

this.formattedPrice = ko.computed({ 
     read: function() { 
      return '$' + this.price().toFixed(2); 
     }, 
     write: function (value) { 
      // Strip out unwanted characters, parse as float, then write the raw data back to the underlying "price" observable 
      value = parseFloat(value.replace(/[^\.\d]/g, "")); 
      this.price(isNaN(value) ? 0 : value); // Write to underlying storage 
     }, 
     owner: this 
    }); 

I udało przykładem jest: Jsfiddle

Dzięki,

Odpowiedz

17

Oto kilka sposobów, które można uczynić to wielokrotnego użytku.

Jeśli chcesz sobie z tym poradzić w swoim modelu widoku, dobrym wyborem jest utworzenie rozszerzenia, które będzie przechowywać sformatowane obliczalne obserwowalne jako "podobieństwo" oryginału. Możesz rozszerzyć obserwowalności za pomocą extenders lub dodając do wspólnego obiektu fn zgodnie z opisem here. Wolę to drugie.

Można dodać funkcję do obserwowalnych o nazwie withCurrencyFormat. To może wyglądać następująco:

ko.observable.fn.withCurrencyFormat = function(precision) { 
    var observable = this; 
    observable.formatted = ko.computed({ 
     read: function (key) { 
      return '$' + (+observable()).toFixed(precision); 
     }, 
     write: function (value) { 
      value = parseFloat(value.replace(/[^\.\d]/g, "")); 
      observable(isNaN(value) ? null : value); // Write to underlying storage 
     }   
    }); 

    return observable; 
}; 

Teraz można powiedzieć:

self.week1Amount = ko.observable(w1).withCurrencyFormat(2); 
self.week2Amount = ko.observable(w2).withCurrencyFormat(2); 
self.week3Amount = ko.observable(w3).withCurrencyFormat(2); 

i wiążą przed nim w interfejsie użytkownika, takich jak:

<td><input data-bind="value: week1Amount.formatted" /></td> 
    <td><input data-bind="value: week2Amount.formatted" /></td> 
    <td><input data-bind="value: week3Amount.formatted" /></td> 

próbki tutaj: http://jsfiddle.net/rniemeyer/xskJN/

Another Wybór polega na przeniesieniu tego na wiązanie, dzięki czemu można zostawić swój model widoku w spokoju. To byłoby użyć podobnego kodu, ale w zwyczaj wiążącego przewodnika, który może wyglądać następująco:

ko.bindingHandlers.valueAsCurrency = { 
    init: function(element, valueAccessor) { 
     var observable = valueAccessor(), 
      formatted = ko.computed({ 
       read: function (key) { 
        return '$' + (+observable()).toFixed(2); 
       }, 
       write: function (value) { 
        value = parseFloat(value.replace(/[^\.\d]/g, "")); 
        observable(isNaN(value) ? null : value); // Write to underlying storage 
       }, 
       disposeWhenNodeIsRemoved: element     
      }); 

     //apply the actual value binding with our new computed 
     ko.applyBindingsToNode(element, { value: formatted }); 
    }   
}; 

tak, to w procedurze obsługi wiążącego jesteśmy tworzyć nasz komputerowej, a następnie za pomocą value wiązania przeciwko niemu.

Teraz twój widok modelu musiałby żadnych zmian i chcesz związać w interfejsie jak:

<td><input data-bind="valueAsCurrency: week1Amount" /></td> 
    <td><input data-bind="valueAsCurrency: week2Amount" /></td> 
    <td><input data-bind="valueAsCurrency: week3Amount" /></td> 

próbki tutaj: http://jsfiddle.net/rniemeyer/sD6y4/

+0

Dzięki, RP. Działa idealnie. –

+0

Mam inne pytanie, jak zastosować to do pola sumy, które jest tylko do odczytu. Ponownie, mój nie działający kod to http://jsfiddle.net/sD6y4/4/. Ponieważ mam sum1, sum2, ..., fields. Czy w tym przypadku możliwe jest korzystanie z funkcji wielokrotnego użytku? Z góry dziękuję! –

+0

Można dodać wiązanie 'textAsCurrency', które po prostu wykonuje część' read' i stosuje powiązanie 'text'. Może wyglądać następująco: http://jsfiddle.net/rniemeyer/3nrKD/ –

Powiązane problemy