首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >KnockoutJS中数字的格式规则

KnockoutJS中数字的格式规则
EN

Stack Overflow用户
提问于 2011-10-09 22:39:53
回答 6查看 63.1K关注 0票数 61

我有一个viewModel,它有一堆带很多小数位的数字。如果我的绑定如下所示:

代码语言:javascript
复制
    <tr>
        <td data-bind="text: Date"></td>
        <td data-bind="text: ActualWeight"></td>
        <td data-bind="text: TrendWeight"></td>
    </tr>

然后,当然,输出包含所有的小数位,并且非常不可读。将绑定更改为这样可以解决问题,但非常冗长且“嘈杂”:

代码语言:javascript
复制
    <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的用途。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-10-10 01:22:42

有几种方法可以处理像这样的情况。您可以选择通过绑定对其进行寻址,或者将其推送到视图模型中。

如果您的视图模型是由映射插件创建的,并且您不想定制它的创建方式,那么您可以考虑使用自定义绑定来处理格式化,它是文本绑定的包装器。

类似于(http://jsfiddle.net/rniemeyer/RVL6q/):

代码语言:javascript
复制
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/):

代码语言:javascript
复制
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;   
}

现在,您可以根据需要绑定myValuemyValue.raw。否则,您可以翻转它并默认返回原始值,并公开一个formatted dependentObservable。当像这样的对象被转换为JSON时,它将丢失任何“子可观察性”,因此如果您要将此数据发送回服务器,则可能需要考虑。

您可以再次使其更通用,并创建一个formattedObservable,其中包含有关如何格式化对象的一些信息。

最后,1.3测试版提供了一个extenders应用程序接口。您可以执行类似于上面的操作:(http://jsfiddle.net/rniemeyer/AsdES/)

代码语言:javascript
复制
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本身。

票数 93
EN

Stack Overflow用户

发布于 2012-07-24 16:34:36

因为knockout现在支持extenders,所以我将使用它们而不是自定义绑定。绑定将如下所示:

代码语言:javascript
复制
<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文档中提供了示例。

票数 22
EN

Stack Overflow用户

发布于 2013-03-12 21:04:16

为了格式化货币和百分比,我创建了用于numeral.min.js的自定义绑定numeralformat.js,可以在http://adamwdraper.github.com/Numeral-js/找到

numeralformat.js (灵感来自dateformat.js和moment.min.js)

代码语言:javascript
复制
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 %)"));
    }
};

视图中的绑定示例。

代码语言:javascript
复制
        <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>
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7704268

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档