KnockoutJS 中数字的格式规则 [英] Formatting rules for numbers in KnockoutJS

查看:19
本文介绍了KnockoutJS 中数字的格式规则的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有很多小数位的数字的视图模型.如果我的绑定看起来像这样:

I have a viewModel with a bunch of numbers with lots of decimal places. If my bindings look like this:

    <tr>
        <td data-bind="text: Date"></td>
        <td data-bind="text: ActualWeight"></td>
        <td data-bind="text: TrendWeight"></td>
    </tr>

然后,当然,输出全是小数位,非常不可读.将绑定更改为如下所示解决了问题,但非常冗长且嘈杂":

Then, of course, the output has all the decimal places and is very unreadable. Changing the bindings to look like this solves the problem, but is very verbose and "noisy":

    <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) 导致标记比此处显示的要混乱得多.

Note, this is one small snippet and having to add .toFixed(1) every place I bind a number leads to much more messy markup than what is shown here.

对于除数字以外的所有内容,覆盖 toString 一直是我控制输出外观的有效方法.关于在我的页面中以某种中心方式告诉淘汰一次的方法的任何建议,在将数字添加到输出之前使用什么函数将数字转换为字符串?

For everything except numbers, overriding the toString has been an effective way for me to control what the output looks like. Any suggestions on a way to tell knockout once, in some central way for my page what function to use to convert numbers into strings before they are added to the output?

就此而言,有一种通用的方法来告诉淘汰赛如何格式化任何类型的值似乎很有用.覆盖 Date.prototype.toString 可以工作,但感觉有点笨手笨脚,因为它可能会影响 .toString 的其他用途,而不仅仅是淘汰赛.

For that matter, having a general purpose way to tell knockout how to format any type of value seems like it would be useful. Overriding Date.prototype.toString works but feels a little heavy handed since it may impact other uses of .toString besides just knockout's.

推荐答案

有几种方法可以处理这种情况.您可以选择通过绑定来解决它,也可以将其推送到您的视图模型中.

There are a couple of ways that you can handle a situation like this one. You can either choose to address it through bindings or push it into your view model.

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

If your view model is created by the mapping plugin and you don't want to get into customizing the way that it is created, then you can consider using a custom binding that is a wrapper to the text binding to handle the formatting.

类似(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",精度:2 }).

It certainly would be possible to create an even more generic binding (formattedText) that either inspected the value and formatted it using some overridable defaults or allowed you to pass in some formatting options ({ type: "numeric", precision: 2 }).

对于您的场景,听起来第一个选项可能是一个不错的选择.但是,如果您想将它推送到您的视图模型中,那么您可以创建一个特殊的 observable,它可以返回该值的格式化版本和原始版本.

For your scenario, it sounds like the first option might be a good choice. However, if you want to push it into your view model, then you could create a special observable that can return both a formatted and a raw version of the value.

它可能类似于 (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;   
}

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

Now you could potentially bind against myValue and myValue.raw depending on your needs. Otherwise, you could flip it and return the raw value by default and expose a formatted dependentObservable. When an object like this is converted to JSON, it will lose any of the "sub-observables", so if you are sending this data back to a server that might be a consideration.

您可以再次使其更通用,并创建一个 formattedObservable 以获取有关如何设置对象格式的一些信息.

You could again make it more generic and create a formattedObservable that takes in some information about how to format the object.

最后,1.3 测试版提供了一个 extenders API.你可以做类似上面的事情:(http://jsfiddle.net/rniemeyer/AsdES/)

Finally, 1.3 beta offers an extenders API. You could do something similar to above like: (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});

Then, apply it to an observable like: var myValue = ko.observable(1.223123).extend({numeric: 1});

您也可以让扩展程序只将 formatteddependentObservable 添加到 target 而不是返回dependentObservable 本身.

You could have the extender also just add a formatted dependentObservable to target instead of returning the dependentObservable itself.

这篇关于KnockoutJS 中数字的格式规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆