【问题标题】:Knockout total value for each row每行的淘汰赛总值
【发布时间】:2013-12-16 23:25:59
【问题描述】:

我想我已经在这个上尝试了所有方法,但我无法弄清楚这一点。当用户增加数量时,我只是试图更新表中每一行的总价格。到目前为止我已经尝试过

  • HTML 中的数学:data-bind="text: parseFloat((total * quantity), 10)"
  • 使用 ko.computed()(“有效”但每行的总计返回相同的值)
  • 订阅事件
  • 使用 ko.utils.arrayForEach 和 jQuery $.each() 循环遍历每个 observableArray 的项目
  • 添加带有 create() 函数的 ko.computed 属性作为映射选项的一部分,但我不太了解那个。

Here's a fiddle。如果有人对我如何完成这个看似简单的任务有任何建议,我将不胜感激。

大多数失败的尝试都在那个小提琴的 cmets 中。我最接近的是 ko.computed 但我只能让它返回一个值 - 表中最后一行的值。谢谢

【问题讨论】:

    标签: jquery knockout.js knockout-mapping-plugin


    【解决方案1】:

    取决于您想要实现的目标。为了简单的显示目的,一个函数会做:

    viewModel.calcTotal = function ( row ) {
        return parseFloat(( row.total() * row.quantity() ), 10);
    };
    

    for 循环中的特殊变量 $data 将传递您的行数据:

    <td><span data-bind="text: $root.calcTotal($data)"></span></td>
    

    此外,如果您添加括号,您在 HTML 中使用数学的第一点将起作用。简单形式的绑定 observables 在表达式中不起作用。

    data-bind="text: parseFloat(( total() * quantity() ), 10)"
    

    【讨论】:

    • 漂亮而简单,正是我想要的。感谢您的帮助!
    【解决方案2】:

    我已经实现了一个工作版本,虽然我不太精通淘汰赛,所以我不确定它是否“正确”。

    参见下面的小提琴http://jsfiddle.net/YeSZ8/7/

    我为每一行创建了一个名为ItemModel 的模型。

    是这样定义的

    var ItemModel = function (arg) {
        var that = this;
    
        this.supplier     = arg.supplier;
        this.itemNumber   = arg.itemNumber;
        this.description  = arg.description;
        this.quantity     = ko.observable(parseInt(arg.quantity, 10));
        this.price        = arg.price;
        this.total        = ko.computed(function () {
            return that.price * that.quantity();
        });
    };
    

    它处理计算新的总值。我没有使用可能更正确的mapping.fromJSON,而是手动加载了json,并在主视图模型中填充了几行。

    编辑:我阅读了一些关于映射插件的信息,我得出的结论是它应该与 create 方法一起使用来启动 ItemModel 实例。

    EDIT2:修复了损坏的过滤,http://jsfiddle.net/YeSZ8/8/

    【讨论】:

    • 谢谢雨果。知道如何使用映射插件来实现这一点吗?
    • @MarkB 我自己没有使用映射插件,但我认为您应该能够为数组中的每个元素创建一个create 后备并启动ItemModel 的实例。
    • 再次感谢,但这就是我在最后一个要点上卡住的地方。
    • @MarkB 我正在研究它,几乎可以使用映射插件。
    • 我也在努力,感谢您的帮助。
    【解决方案3】:

    这是一个使用映射插件的解决方案:

    ....
    var mappingOptions = {
        'cartItemsList': {
            create: function (options) {
                var result = ko.mapping.fromJS(options.data, {});
                result.total = ko.computed(function () {
                    return result.quantity() * parseFloat(result.price());
                });
                return result;
            }
        }
    };
    
    var model = {cartItemsList: JSON.parse(jsonData)};
    var viewModel = ko.mapping.fromJS(model, mappingOptions);
    viewModel.filter = ko.observable("");
    ...
    

    改编的小提琴:http://jsfiddle.net/YeSZ8/10/

    【讨论】:

    • 过滤不适用于这个。我确信我可以通过一些更改让它工作,但是在这篇文章中选择的答案是一个非常简单的选项。感谢您的帮助
    猜你喜欢
    • 2012-06-12
    • 2013-11-25
    • 2015-05-24
    • 2013-12-27
    • 1970-01-01
    • 1970-01-01
    • 2017-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多