KnockoutJS의 숫자 서식 규칙
소수 자릿수가 많은 숫자가 많은 viewModel이 있습니다. 내 바인딩이 다음과 같은 경우 :
<tr>
<td data-bind="text: Date"></td>
<td data-bind="text: ActualWeight"></td>
<td data-bind="text: TrendWeight"></td>
</tr>
물론 출력에는 소수점 이하 자릿수가 모두 포함되어 읽기가 매우 어렵습니다. 바인딩을 이렇게 변경하면 문제가 해결되지만 매우 장황하고 "노이즈"합니다.
<tr>
<td data-bind="text: Date"></td>
<td data-bind="text: ActualWeight().toFixed(1)"></td>
<td data-bind="text: TrendWeight().toFixed(1)"></td>
</tr>
이것은 하나의 작은 스 니펫이며 숫자를 바인딩하는 모든 위치에 .toFixed (1)를 추가해야 여기에 표시된 것보다 훨씬 더 지저분한 마크 업이 발생합니다.
숫자를 제외한 모든 경우에 toString을 재정의하는 것은 출력이 어떻게 보이는지 제어하는 효과적인 방법이었습니다. 한 번 녹아웃을 알리는 방법에 대한 제안 사항은 출력에 추가되기 전에 숫자를 문자열로 변환하는 데 사용할 기능이 무엇입니까?
그 문제에 대해, 모든 유형의 값을 형식화하는 방법을 녹아웃에게 알리는 일반적인 목적의 방법을 갖는 것이 유용 할 것 같습니다. Date.prototype.toString을 재정의하는 것은 작동하지만 녹아웃 외에 .toString의 다른 사용에 영향을 미칠 수 있기 때문에 약간 무겁게 느껴집니다.
이와 같은 상황을 처리 할 수있는 몇 가지 방법이 있습니다. 바인딩을 통해 주소를 지정하거나 뷰 모델로 푸시 할 수 있습니다.
뷰 모델이 매핑 플러그인에 의해 생성되고 생성 방식을 사용자 지정하지 않으려는 경우 텍스트 바인딩에 대한 래퍼 인 사용자 지정 바인딩을 사용하여 서식을 처리하는 것을 고려할 수 있습니다.
( http://jsfiddle.net/rniemeyer/RVL6q/ ) :
ko.bindingHandlers.numericText = {
update: function(element, valueAccessor, allBindingsAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor()),
precision = ko.utils.unwrapObservable(allBindingsAccessor().precision) || ko.bindingHandlers.numericText.defaultPrecision,
formattedValue = value.toFixed(precision);
ko.bindingHandlers.text.update(element, function() { return formattedValue; });
},
defaultPrecision: 1
};
값을 검사하고 재정의 가능한 기본값을 사용하여 형식을 지정하거나 일부 형식 지정 옵션 ( { type: "numeric", precision: 2 }
) 을 전달할 수있는 훨씬 더 일반적인 바인딩 (formattedText)을 만드는 것이 가능합니다 .
시나리오의 경우 첫 번째 옵션이 좋은 선택 일 수 있습니다. 그러나 뷰 모델에 푸시하려면 형식화 된 값과 원시 버전을 모두 반환 할 수있는 특수 관찰 가능 항목을 만들 수 있습니다.
다음과 같을 수 있습니다 ( http://jsfiddle.net/rniemeyer/fetBG/ ) :
function formattedNumericObservable(initialValue, precision) {
var _raw = ko.observable(initialValue),
precision = precision || formattedNumericObservable.defaultPrecision,
//the dependentObservable that we will return
result = ko.dependentObservable({
read: function() {
return _raw().toFixed(precision);
},
write: _raw
});
//expose raw value for binding
result.raw = _raw;
return result;
}
지금 당신은 가능성에 대한 결합 수 myValue
와 myValue.raw
사용자의 요구에 따라. 그렇지 않으면 뒤집어서 기본적으로 원시 값을 반환하고 formatted
dependentObservable을 노출 할 수 있습니다. 이와 같은 객체가 JSON으로 변환되면 "하위 관찰 가능 항목"이 손실되므로이 데이터를 서버로 다시 보내는 경우 고려해야 할 사항이 있습니다.
다시 좀 더 일반적으로 만들고 formattedObservable
개체 형식 지정 방법에 대한 정보를 가져 오는를 만들 수 있습니다 .
마지막으로 1.3 베타는 extenders
API를 제공합니다 . 위와 비슷한 작업을 수행 할 수 있습니다. ( http://jsfiddle.net/rniemeyer/AsdES/ )
ko.extenders.numeric = function(target, precision) {
var result = ko.dependentObservable({
read: function() {
return target().toFixed(precision);
},
write: target
});
result.raw = target;
return result;
};
그런 다음 다음과 같은 관찰 가능 항목에 적용하십시오. var myValue = ko.observable(1.223123).extend({numeric: 1});
extender는 dependentObservable 자체를 반환하는 대신에 formatted
dependentObservable을 추가 할 수도 target
있습니다.
녹아웃은 이제 익스텐더를 지원하므로 사용자 지정 바인딩 대신 익스텐더 를 사용합니다. 바인딩은 다음과 같습니다.
<tr>
<td data-bind="text: Date.extend({format : 'date'})"></td>
<td data-bind="text: ActualWeight.extend({format : 'weight'})"></td>
<td data-bind="text: TrendWeight.extend({format : 'weight'})"></td>
</tr>
format
이 경우 익스텐더 를 작성해야합니다 . 녹아웃 문서에 예제가 제공됩니다.
통화 및 퍼센트 형식을 지정하기 위해 http://adamwdraper.github.com/Numeral-js/ 에서 찾을 수있는 numeric.min.js와 함께 사용할 사용자 지정 바인딩 numericformat.js를 만들었습니다.
numericformat.js (dateformat.js 및 moment.min.js에서 영감을 얻음)
var formatNumber = function (element, valueAccessor, allBindingsAccessor, format) {
// Provide a custom text value
var value = valueAccessor(), allBindings = allBindingsAccessor();
var numeralFormat = allBindingsAccessor.numeralFormat || format;
var strNumber = ko.utils.unwrapObservable(value);
if (strNumber) {
return numeral(strNumber).format(numeralFormat);
}
return '';
};
ko.bindingHandlers.numeraltext = {
init: function (element, valueAccessor, allBindingsAccessor) {
$(element).text(formatNumber(element, valueAccessor, allBindingsAccessor, "(0,0.00)"));
},
update: function (element, valueAccessor, allBindingsAccessor) {
$(element).text(formatNumber(element, valueAccessor, allBindingsAccessor, "(0,0.00)"));
}
};
ko.bindingHandlers.numeralvalue = {
init: function (element, valueAccessor, allBindingsAccessor) {
$(element).val(formatNumber(element, valueAccessor, allBindingsAccessor, "(0,0.00)"));
//handle the field changing
ko.utils.registerEventHandler(element, "change", function () {
var observable = valueAccessor();
observable($(element).val());
});
},
update: function (element, valueAccessor, allBindingsAccessor) {
$(element).val(formatNumber(element, valueAccessor, allBindingsAccessor, "(0,0.00)"));
}
};
ko.bindingHandlers.percenttext = {
init: function (element, valueAccessor, allBindingsAccessor) {
$(element).text(formatNumber(element, valueAccessor, allBindingsAccessor, "(0.000 %)"));
},
update: function (element, valueAccessor, allBindingsAccessor) {
$(element).text(formatNumber(element, valueAccessor, allBindingsAccessor, "(0.000 %)"));
}
};
ko.bindingHandlers.percentvalue = {
init: function (element, valueAccessor, allBindingsAccessor) {
$(element).val(formatNumber(element, valueAccessor, allBindingsAccessor, "(0.000 %)"));
//handle the field changing
ko.utils.registerEventHandler(element, "change", function () {
var observable = valueAccessor();
observable($(element).val());
});
},
update: function (element, valueAccessor, allBindingsAccessor) {
$(element).val(formatNumber(element, valueAccessor, allBindingsAccessor, "(0.000 %)"));
}
};
View의 바인딩 예.
<td><label>Available Commitment Balance:</label> </td>
<td>
<!-- ko with: SelectedLoan -->
<span data-bind="numeraltext: AvailableCommitmentAmount"></span>
<!-- /ko -->
</td>
<td><label> % Interest Rate:</label></td>
<td>
<!-- ko with: SelectedLoan -->
<input data-bind="percentvalue: InterestRatePercent" />
<!-- /ko -->
</td>
<td><label> $ Amount To Transfer:</label></td>
<td>
<!-- ko with: SelectedLoan -->
<input class="inputsmall" data-bind="numeralvalue: FundsHeldTotalAmount" />
<!-- /ko -->
</td>
위에서 받아 들여진 답변을 기반으로합니다. RP Niemeyers 바이올린을 포크하여 쉼표 형식도 추가했습니다. 따라서 10001.232가 있으면 10,001.232로 형식이 지정됩니다. 가격을 다루는 경우 매우 중요합니다. 다시 말하지만 이것은 그저 답을 기반으로하고 있습니다.
<div data-bind="numericText: myValue"></div>
<div data-bind="numericText: myValue, positions: 3"></div>
<div data-bind="numericText: myValue, positions: myPositions"></div>
<input data-bind="value: myPositions" />
<div>
<br>
just testing commas<br>
<input type=text id="withComma" readonly/>
</div>
ko.bindingHandlers.numericText = {
update: function(element, valueAccessor, allBindingsAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
var positions= ko.utils.unwrapObservable(allBindingsAccessor().positions) || ko.bindingHandlers.numericText.defaultPositions;
var formattedValue = value.toFixed(positions);
var finalFormatted = ko.bindingHandlers.numericText.withCommas(formattedValue);
ko.bindingHandlers.text.update(element, function() { return finalFormatted ; });
},
defaultPositions: 2,
withCommas: function(original){
original+= '';
x = original.split('.');
x1 = x[0];
x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}
};
var viewModel = {
myValue: ko.observable(12673.554),
myPositions: ko.observable(4)
};
ko.applyBindings(viewModel);
/*Just testing the function below, you don't need thsi....*/
function addCommas(nStr)
{
nStr += '';
x = nStr.split('.');
x1 = x[0];
x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}
var formatted = addCommas('1070781.493')
$('#withComma').val(formatted);
jQuery Globalize 플러그인을 사용하여 서식 지정에 접근했습니다. 여기에 서식 핸들러의 내 버전입니다, textFormatted
및 valueFormatted
텍스트와 값 바인딩에 대한 래퍼는 각각이다.
사용법은 다음과 같습니다.
<span data-bind="textFormatted: Amount, pattern: 'n'" />
선택적으로 문화도 지정할 수 있습니다. 하지만 이런 종류의 컨트롤은 HTML에 속해서는 안된다고 생각 합니다만, 개발이나 디버깅시 도움이 될 수 있습니다.
<input data-bind="valueFormatted: Amount, pattern: 'n', culture: 'et'" type="text" />
Values for pattern
property/binding must be any of suitable formats that Globalize.format( value, format, [locale] )
function's format
param expects. Same goes for culture
property/binding that will be used in optional locale
param. Globalize reference.
Binding definitions:
(function() {
function getFormatedOrPlainResult(value, allBindingsAccessor) {
var pattern = allBindingsAccessor.get('pattern');
if (pattern == null || !/\S*/.test(pattern)) {
return value;
}
var valueToFormat = pattern === 'd' ? new Date(value) : value;
return Globalize.format(valueToFormat, pattern, allBindingsAccessor.get('culture'));
};
ko.bindingHandlers.textFormatted = {
init: ko.bindingHandlers.text.init,
update: function(element, valueAccessor, allBindingsAccessor) {
var result = getFormatedOrPlainResult(ko.unwrap(valueAccessor()), allBindingsAccessor);
ko.bindingHandlers.text.update(element, function() { return result; });
}
};
ko.bindingHandlers.valueFormatted = {
init: function(element, valueAccessor, allBindingsAccessor) {
var result = getFormatedOrPlainResult(ko.unwrap(valueAccessor()), allBindingsAccessor);
ko.bindingHandlers.value.init(element, function() { return result; }, allBindingsAccessor);
},
update: function(element, valueAccessor, allBindingsAccessor) {
var result = getFormatedOrPlainResult(ko.unwrap(valueAccessor()), allBindingsAccessor);
ko.bindingHandlers.value.update(element, function() { return result; }, allBindingsAccessor);
}
};
}());
If it's just about displaying a localized number of a text binding, a very easy way is to use toLocaleString()
<tr>
<td data-bind="text: ActualWeight().toLocaleString()"></td>
<td data-bind="text: TrendWeight().toLocaleString()"></td>
</tr>
For more information visit page.
참고URL : https://stackoverflow.com/questions/7704268/formatting-rules-for-numbers-in-knockoutjs
'Development Tip' 카테고리의 다른 글
SQL Server 2000 : 저장 프로 시저를 종료하는 방법은 무엇입니까? (0) | 2020.12.03 |
---|---|
if 문에 상수를 먼저 넣는 이유는 무엇입니까? (0) | 2020.12.03 |
연결 호출을위한 모의 또는 스텁 (0) | 2020.12.03 |
JUnit을 사용한 내부 클래스의 테스트 케이스 (0) | 2020.12.03 |
자바 스크립트 개체 키 이름 가져 오기 (0) | 2020.12.03 |