【问题标题】:Computed function issue with KnockOutKnockOut 的计算函数问题
【发布时间】:2013-05-14 13:11:08
【问题描述】:

使用 KnockOut - 在添加到 MVC .Net 代码之前,我正在尝试构建主细节/项目应用程序的基础知识。

我想要做的只是有一个简单的项目、价格、税金 - 以及一个计算列来显示每个项目的含税金额:

客户端 KnockOut 视图模型是:

var GiftModel = function(gifts) {
var self = this;
self.gifts = ko.observableArray(gifts);

 self.formattedPrice = ko.computed(function() {
    var pricet = self.gifts().price;
    return pricet ? "$" + pricet.toFixed(2) * (1 + self.gifts().tax : "None"; 

});    

self.addGift = function() {
    self.gifts.push({
        name: "",
        price: "",
        tax:0
    });
};

self.removeGift = function(gift) {
    self.gifts.remove(gift);
};

self.save = function(form) {
    alert("Could now transmit to server: " + ko.utils.stringifyJson(self.gifts));
    // To actually transmit to server as a regular form post, write this: ko.utils.postJson($("form")[0], self.gifts);
};
};

var viewModel = new GiftModel([
{ name: "Tall Hat", price: "39.95", tax:17.5},
{ name: "Long Cloak", price: "120.00", tax:20}
]);
ko.applyBindings(viewModel);

// Activate jQuery Validation
$("form").validate({ submitHandler: viewModel.save });

表格标记为:

<table data-bind='visible: gifts().length > 0'>
        <thead>
            <tr>
                <th>Gift name</th>
                <th>Price</th>
                <th>Tax</th>
                <th />
            </tr>
        </thead>
        <tbody data-bind='foreach: gifts'>
            <tr>
                <td><input class='required' data-bind='value: name, uniqueName: true' /></td>
                <td><input class='required number' data-bind='value: price, uniqueName: true' /></td>
                 <td><input class='required number' data-bind='value: tax, uniqueName: true' /></td>
               <td data-bind='text: formattedPrice'></td>
                <td><a href='#' data-bind='click: $root.removeGift'>Delete</a></td>

            </tr>
        </tbody>
    </table>

    <button data-bind='click: addGift'>Add Gift</button>
    <button data-bind='enable: gifts().length > 0' type='submit'>Submit</button>

由于formattedPrice 函数似乎无法正常工作,它正在停止。

我在这里找到了一个 jsfiddle:http://jsfiddle.net/marktait/TR6Sy/ - 谁能帮我克服这个看似简单的障碍?

谢谢,

标记

【问题讨论】:

    标签: javascript jquery knockout.js


    【解决方案1】:

    问题是您在循环礼物列表时调用了计算函数。但是,计算方法不适用于给定的礼物,而是适用于所有礼物。你有两个选择:

    您可以使每个礼物对象都是具有此计算方法的对象(如用户 Brandon 建议的那样),或者您只需将其转换为将礼物作为参数的普通函数,如下所示:

    self.getFormattedPrice = function(price, tax) {
        var val = price ? "$" + parseFloat(price).toFixed(2) * (1 + tax) : "None";
        return val;
    };    
    

    然后,你可以这样称呼它:

    <td data-bind='text: $parent.getFormattedPrice(price, tax)'></td>
    

    我已经更新了你的fiddle

    【讨论】:

    • 嗨 - 谢谢。我认为添加一行并更改其上的任何内容(即文本框中的税额)会很简单,并且价格会自动重新计算。我可能已经期待太多了。感谢您的宝贵时间。
    【解决方案2】:

    self.gifts() 是一个数组。但是在您的计算中,您试图将其用作单个值。那是行不通的。您需要将其作为计算属性添加到数组中的每个项目:

    var addFormattedPrice = function (gift) {
       gift.formattedPrice = ko.computed(function () {
           var pricet = gift.price;
           return pricet ? "$" + pricet.toFixed(2) * (1 + gift.tax : "None"; 
       });
    };
    
    ko.utils.arrayForEach(self.gifts(), addFormattedPrice);
    
    self.addGift = function() {
        var gift = {
            name: "",
            price: "",
            tax:0
        };
        addFormattedPrice(gift);
        self.gifts.push(gift);
    };
    

    【讨论】:

    • 嗨 - 我添加了它并更新了小提琴:jsfiddle.net/marktait/TR6Sy/6 - 它仍然没有显示第二行,或者允许添加更多内容(再次出现 404 错误)。
    【解决方案3】:

    看起来你只是缺少一个右括号 -

    return pricet ? "$" + pricet.toFixed(2) * (1 + self.gifts().tax : "None"; 
    

    应该是

    return pricet ? "$" + pricet.toFixed(2) * (1 + self.gifts().tax) : "None"; 
    

    【讨论】:

    • 嗨 - 我添加了,但同样的事情发生了 - 它最初显示一行,然后不再显示(来自 JSON 数据) - 单击添加礼物会出现 404 错误。谢谢,马克
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    • 1970-01-01
    • 2014-08-28
    • 2021-07-20
    相关资源
    最近更新 更多