【问题标题】:JavaScript - Prototype function vs. ViewModel function?JavaScript - 原型函数与 ViewModel 函数?
【发布时间】:2016-10-04 12:40:49
【问题描述】:

我想知道是否有理由更喜欢原型函数/viewModel 函数。

假设您想将整数 1234 表示为货币值,例如 12.34€

我所做的是,在Number 对象上创建一个原型函数:

Number.localeSeparator = 1.1.toLocaleString().substr(1, 1);

Number.prototype.centToEuro = function (separator_string) {
    if (!separator_string) {
        separator_string = Number.localeSeparator;
    }
    return (this / 100).toFixed(2).replace(".", separator_string) + "€";
}

var vm = {myMoney: ko.observable(1234)};
ko.applyBindings(vm);

这使得数据绑定相当容易,因为我需要在视图中做的就是:

<div data-bind="text: myMoney().centToEuro()"></div>

除了原型函数,我还可以使用几乎相同的代码创建 viewModel 函数,如下所示:

var vm = {
    myMoney: ko.observable(1234),
    localeSeparator: 1.1.toLocaleString().substr(1, 1),
    centToEuro: function (value_int, separator_string) {
        if (!separator_string) {
            separator_string = vm.localeSeparator;
        }
        return (value_int / 100).toFixed(2).replace(".", separator_string) + "€";
    }
}
ko.applyBindings(vm);

在视图中使用,它看起来像这样:

<div data-bind="text: centToEuro(myMoney())"></div>

如您所知,这两条 HTML 行的长度几乎完全相同,只是方法不同。所以问题是,更喜欢哪种方法?

【问题讨论】:

    标签: javascript function knockout.js prototype viewmodel


    【解决方案1】:

    鉴于centToEuro 与任意数字无关,而是与您在此处处理的特定货币模型有关,并且您不应该扩展内置原型对象,请使用 viewmodel 函数。

    【讨论】:

    • 好吧,有道理。如果有人想对任意数字使用自定义函数?是否可以对此做出一般性陈述,还是取决于用例是否扩展原型?
    • 在这种情况下,它通常仍被视为bad idea(另请参阅那里的 cmets 中的链接)。
    【解决方案2】:

    不就是你问题的意思吗,把这个函数放在哪里?

    考虑将扩展器用于货币格式化等任务,您只需设置一次,即可随处使用。只是一个例子:

    ko.extenders.currency = function (target, option) {
        target.amount = function () {
            var amt = ko.unwrap(target);
            var localeSeparator = 1.1.toLocaleString().substr(1, 1);
            switch(option) {
                case "Eur":
                    amt = (amt / 100).toFixed(2).replace(".", localeSeparator) + "€";
                    break;
                default:;
                }
            return amt;
        };
        return target;
    };
    

    查看模型:

    myMoney: ko.observable("1234").extend({currency: "Eur"})
    

    标记:

    <div data-bind="text: myMoney.amount()"></div>
    

    【讨论】:

    • 这个答案实际上对那个特定的问题非常有帮助,为此竖起大拇指。但我的问题是真的,这被认为是一种更好的做法,例如用于辅助功能(如本例所示)。独立于 MVVM 模式(和 Knockout),我根本不知道为什么我应该更喜欢一种方法而不是另一种方法,因为似乎没有一种方法在成本性能、空间、稳定性或其他方面。
    猜你喜欢
    • 2010-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 2018-05-25
    • 1970-01-01
    • 1970-01-01
    • 2010-12-24
    相关资源
    最近更新 更多