KnockoutJS-行和列计算 [英] KnockoutJS - Row and Column Calculations

查看:106
本文介绍了KnockoutJS-行和列计算的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是我最初提出的第一个问题,即'嵌套数据,正在加载子对象".

This question follows on from my original and first question 'Nested Data, Loading Children'.

我有一个表,其中填充了包含嵌套对象的JSON数据(请参阅颜色编码).该表包含每个对象可编辑的一行.这称为分配"行.

I have a table which is populated with data from JSON that contains nested objects (see colour coding). The table contains one row per object that is editable. This is called the 'Allocation' row.

这些值是从JSON对象("Values":{ n":4,"n2":2等等).

These values are populated from a JSON object ("Values": { " n" : 4 , "n2" : 2, etc).

首先,我想显示每个可编辑行的总计.当值在行内更新时,总更新.这个用例的背后是我想将原始总数(Allocation.Total)与可观察的总数进行比较,因此我可以更改控件单元格上的css类,以指示数据是否已更改.

Firstly I would like to display a total for each editable row. As values are updated inside the row the total updates. This use case behind this is I would like to compare the original total (Allocation.Total) with the observable total, so I can then change the css class on the controls cell to indicate if the data has changed.

如下所示; (黄色表示用户更改)

This is illustrated below; (yellow indicated user changes)

http://i.stack.imgur.com/XQpLp.jpg

问题的第二部分涉及列总计.上面的问题是让我的头部有点受伤,但是这个让我很震惊.这样,我就睡在那个问题上,等问题变得更清楚后再更新问题.

The second part of the question is dealing with a Column total. The above question was making my head hurt a little, but this one blows my mind. As such I'm will sleep on that one, and then update the question once it's become a little clearer.

使用简化的数据模型会产生一种复杂性.通过说一切都是同一类型的对象,(乘员)当节点有子代时,用于分配的单词需要改变.如果该节点具有子级,则分配"应称为向导.

There is one complication which as arisen from using a simplified data model. In that by saying everything is the same type of object, (crew) the word used for Allocation needs to change when the node has children. If the node has Children 'Allocation' should be called Guide.

此处的简化代码示例...

已更新为列部分... Allocated.Total,是分配的运行总计.此处的区别是总数正在表的各个列下工作,而不是跨单个行.这有可能吗?我的心开始有点融化.

Updated with the Column Part... The Allocated.Total, is a running total of the Allocations. The difference here is this total is working down the columns of the table, no across a single row. Is this even possible? My mind started to melt a little.

更新-4月26日

对于列总计,尽管可以通过对node1,node2,node3进行硬编码来实现.我曾希望避免这种情况,因为这些节点会根据用户/请求而变化(例如,它不一定总是node1,node2,node3).我已经在HTML模板中解决了这个问题,因为可以在服务器端找到此信息,从而使我能够提供具有正确绑定的页面.

For the Column totals although it is possible to approach this by hardcoding against node1, node2, node3. I had hoped to avoid this because these are nodes that change depending on the user/request (e.g. it won't always be node1, node2, node3). I've addressed this issue in the HTML templating as this information can be found out server side, enabling me to deliver the page with the correct bindings.

我可以对JavaScript使用相同的方法,但是当我们从API加载数据时,必须有可能动态获取此信息,然后JavaScript仍然保持简洁.我一直在研究如何遍历(键,对)值,因此node1,node2,node3位可以变为动态.但是,这是我很困的地方.

I could use the same approach for the JavaScript but as we load the data in from the API, it must be possible to dynamically get this information and then the JavaScript remains nice and clean. I've been looking at how to iterate over (key, pair) values, so the node1, node2, node3 bit can become dynamic. However this is where I got quite stuck.

第二部分,它变得非常复杂.总计是我追求的一部分,但我还需要每个单独列的总计(星期一-早餐,星期一-午餐,星期一-晚餐).这从最深的节点到最上端都是级联的.

The second part, where it gets really complex. The Grand Total is part of what I am after, but I also need a total for each individual column (Monday - Breakfast, Monday - Lunch, Monday - Diner). This cascades from the deepest node, up to the very top.

赎回者也是如此.因此,一个人可以赎回票证,该票证一直反映到父节点.作为爱XPath的人,这将是祖先或自己::乘员组.

The same is true also of Redeemed. So a person can redeem a ticket, which is reflected all the way up to the parent node. As someone who loves XPaths, this would be ancestor-or-self::Crew.

推荐答案

确定.这是您应计算的总数.

OK. Here's what your total computed should be.

self.totalAllocation = ko.computed(function() {
            var values = self.Allocation.Values;
            return Number(values.node1()) + 
                   Number(values.node2()) + 
                   Number(values.node3());
})

请注意节点周围的括号.这表明这些已更改为可观察到的观测值.在您当前的代码中,它们只是json值.不可观察值可以绑定到/来自剔除值/文本绑定,但是当它们的值更改时,它们不会通知其他人.如果totalAllocation使用的是简单的json值,则当它们通过您的值绑定更改时,不会自动重新计算.

Note the brackets around the nodes. This indicates that these have been changed into knockout observables. In your current code they are simply json values. Non-observables can be bound to/from knockout value/text bindings but they do not notify others when their value has changed. If the totalAllocation was using simple json values it would not automatically recompute when they changed via your value bindings.

我更新了您的示例以使用映射插件.这将自动旋转所有属性并使它们可观察.

I updated your example to use the mapping plugin. This will automatically spin through all your properties and make them observables.

分配标签很简单.这可以通过计算绑定和文本绑定来实现.

The label for allocation is a simple one. This can be achieved with a computed and text binding.

self.allocLabel = ko.computed(function() {
    return self.HasChildren() ? "Guide" : "Allocation";            
});

<th data-bind="text: allocLabel">Allocation</th>

我对最后一部分并不清楚.似乎您希望Allocated.Total对其所有子分配进行求和.这包括兑换的价值吗?是否应该包括自己分配的总数?不管答案是什么,答案都是通过可计算的可观察到的.

I wasn't completely clear on the last part. It seems like you want the Allocated.Total to sum all its child allocations. Does this include the Redeemed value? Should it include its own allocated total? Whatever the answer the way to do it is with a computed observable again.

类似.

self.grandTotal = ko.computed(function() {
    var result = 0;              
    for (var i = 0; i < self.Crews().length; i += 1) {
        result += self.Crews()[i].totalAllocation();
    }   
    return result;
});

您可以看到我只是遍历了Crews数组,并对每个孩子的totalAllocation求和.如果您更新行分配编号,则行总数和列总数都会更新.

You can see I simply looped through the Crews array and summed the totalAllocation for each child. If you update a rows allocation numbers the row total and column total get updated.

http://jsfiddle.net/madcapnmckay/CGBZe/

编辑

如评论中所述.动态总计不应成为问题(未经测试).

As mentioned in the comments. Dynamic totals should not be an issue (untested).

self.totalAllocation = ko.computed(function() {
     var values = self.Allocation.Values;
     var total = 0;
     for (var prop in values) { 
         total += Number(ko.utils.unwrapObservable(values[prop]));
     }
     return total;
})

希望这会有所帮助.

这篇关于KnockoutJS-行和列计算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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