Hier sind ein paar Möglichkeiten, wie Sie diese wiederverwendbar zu machen.
Wenn Sie dies in Ihrem Ansichtsmodell handhaben möchten, ist es eine gute Wahl, eine Erweiterung zu erstellen, die das formatierte, berechnete Observable als "Unterbeobachtungsobjekt" Ihres Originals speichert. Sie können Observables unter Verwendung von extenders oder durch Hinzufügen zum gemeinsamen Objekt fn
wie beschrieben here erweitern. Ich bevorzuge Letzteres.
So könnten Sie Observablen eine Funktion hinzufügen, die withCurrencyFormat
genannt wird. Es könnte wie folgt aussehen:
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;
};
Jetzt können Sie sagen:
self.week1Amount = ko.observable(w1).withCurrencyFormat(2);
self.week2Amount = ko.observable(w2).withCurrencyFormat(2);
self.week3Amount = ko.observable(w3).withCurrencyFormat(2);
und binden dagegen in der Benutzeroberfläche wie:
<td><input data-bind="value: week1Amount.formatted" /></td>
<td><input data-bind="value: week2Amount.formatted" /></td>
<td><input data-bind="value: week3Amount.formatted" /></td>
Beispiel hier: http://jsfiddle.net/rniemeyer/xskJN/
Another Die Wahl besteht darin, diese in eine Bindung zu verschieben, sodass Sie Ihr Ansichtsmodell in Ruhe lassen können. Dies würde einen ähnlichen Code verwenden, aber in einer benutzerdefinierten Bindung Handler, aussehen könnte:
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 });
}
};
Also, in der Bindung Handler wir schaffen unsere berechneten und mit dann den value
Bindung dagegen.
Nun wäre Ihrer Ansicht nach Modell keine Änderungen benötigen und Sie würden in der Benutzeroberfläche binden wie:
<td><input data-bind="valueAsCurrency: week1Amount" /></td>
<td><input data-bind="valueAsCurrency: week2Amount" /></td>
<td><input data-bind="valueAsCurrency: week3Amount" /></td>
Beispiel hier: http://jsfiddle.net/rniemeyer/sD6y4/
Danke, RP. Es funktioniert perfekt. –
Ich habe eine andere Frage, wie Sie dies auf das Summenfeld anwenden, das schreibgeschützt ist. Auch hier ist mein nicht funktionierender Code http://jsfiddle.net/sD6y4/4/. Da ich sum1, sum2, ..., Felder habe. Ist es in diesem Fall möglich, eine wiederverwendbare Funktion zu machen? Danke im Voraus! –
Sie könnten eine 'textAsCurrency'-Bindung hinzufügen, die nur den' read'-Teil ausführt und die 'text'-Bindung anwendet. Könnte aussehen wie: http://jsfiddle.net/rniemeyer/3nrKD/ –