我有一个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一直是我控制输出内容的有效方法。有什么建议可以让我的页面在将数字添加到输出之前,使用什么函数将数字转换为字符串?
在这个问题上,拥有一种通用的方法来告诉knockout如何格式化任何类型的值似乎是有用的。覆盖Date.prototype.toString是可行的,但感觉有点笨手笨脚,因为它可能会影响.toString的其他用途,而不仅仅是knockout的用途。
发布于 2011-10-10 01:22:42
有几种方法可以处理像这样的情况。您可以选择通过绑定对其进行寻址,或者将其推送到视图模型中。
如果您的视图模型是由映射插件创建的,并且您不想定制它的创建方式,那么您可以考虑使用自定义绑定来处理格式化,它是文本绑定的包装器。
类似于(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
};
当然,也可以创建一个更通用的绑定(formattedText),它可以检查值并使用一些可覆盖的默认值对其进行格式化,也可以允许您传入一些格式化选项({ type: "numeric", precision: 2 }
)。
对于您的场景,听起来第一个选项可能是一个很好的选择。但是,如果您希望将其推送到视图模型中,则可以创建一个特殊的可观察对象,该对象可以同时返回值的格式化版本和原始版本。
它可能类似于(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
应用程序接口。您可以执行类似于上面的操作:(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});
您也可以让扩展器只向target
添加一个formatted
dependentObservable,而不是返回dependentObservable本身。
发布于 2012-07-24 16:34:36
因为knockout现在支持extenders,所以我将使用它们而不是自定义绑定。绑定将如下所示:
<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
扩展器。knockout文档中提供了示例。
发布于 2013-03-12 21:04:16
为了格式化货币和百分比,我创建了用于numeral.min.js的自定义绑定numeralformat.js,可以在http://adamwdraper.github.com/Numeral-js/找到
numeralformat.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 %)"));
}
};
视图中的绑定示例。
<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>
https://stackoverflow.com/questions/7704268
复制相似问题