我正在使用web application
使用Asp.Net Mvc
,其中我使用knockout Js通过对数据执行某些操作来检索并将数据发送到Html View。
例如,我在名为datainput
Grade Type Volume Price
A Buy 1000 10
A Sell 1200 10
B Sell 100 100
我正在计算一个数组,这样当在html页面上显示时,它只需要一个不同的Grade值,并将该等级下的数据分组,如
A
Buy 1000 10
Sell 1200 10
B
Sell 100 100
使用上述功能如下
self.uniqueSelect = ko.dependentObservable(function () {
var Transactiontypes = ko.utils.arrayMap(self.datainput(), function (item) { return item.Grade })
return ko.utils.arrayGetDistinctValues(Transactiontypes);
});
我不认为上面的脚本存在问题,但不确定但是我继续使用从上面的脚本中获取的数据并尝试将其填充到html,如下所示
<!--ko foreach: uniqueSelect-->
<tr>
<td class="clientproductHeader" data-bind="text: $data"></td>
<td class="clientproductHeader" colspan="10"></td>
</tr>
<tbody data-bind="foreach: ko.observableArray($root.datainput()).extendsdistinct('Grade').index.Grade()[$data]">
<tr>
<script type="text/html" id="read-template">
<td data-bind="text: Type"></td>
<td data-bind="text: Volume"></td>
<td data-bind="text: (typeof Price() === 'number') ? Price().toFixed(2) : '' "></td>
</script>
</tr>
</tbody>
<!--/ko-->
</table>
上述脚本由于某些原因显示重复数据,例如如果等级重复两次,如示例数据中那样,它会显示该等级的相同数据两次,如果重复三次,则显示三次,依此类推。 / p>
我认为错误是<!--ko foreach: uniqueSelect-->
,因为它只是根据相似等级的数量来循环数据。
结果就像
A
Buy 1000 10
Sell 1200 10
B
Sell 100 100
A
Buy 1000 10
Sell 1200 10
在上述数据中,A级重复两次,因此所有A级数据重复两次,因为B级只有一个条目,因此,它只发生一次 我收到的数据屏幕 不知道如何处理这个
答案 0 :(得分:1)
我经历了一个版本,它做了我认为你想要完成的事情。它使用Pēteris描述的方法。 See it in action
您希望保持视图代码尽可能简单,并且要小心重新回到$root
。如果你是积极的,你想用过滤器做一个,做一个类似下面的分组,然后迭代它的每个条目/孩子。另外,尽量避免在视图中声明observable。
最后,您可以将groupByGrade()
和getGrades()
合并到一个函数中,该函数返回一个具有每个结果的属性的对象。它会节省迭代周期。
观点:
<tr>
<td class="clientproductHeader" data-bind="text: 'Grade ' + $data + ' (' + $root.log()[$data].length + ' trades)'"></td>
<td class="clientproductHeader" colspan="10"></td>
</tr>
<tbody data-bind="foreach: $root.log()[$data]">
<tr>
<td data-bind="text: type"></td>
<td data-bind="text: volume"></td>
<td data-bind="text: (typeof price === 'number') ? price.toFixed(2) : '' "></td>
<td class="actioncells">
<a class="btn btn-success" title="Edit" data-bind="click: $root.edit">Edit</a>
</td>
<td class="actioncells">
<a class="btn btn-danger" title="Delete " data-bind="click: $root.remove">Delete</a>
</td>
</tr>
</tbody>
<!--/ko-->
JavaScript:
function testViewModel() {
// Underscore and Lo-dash both have a function to group
// an object by key. That's what you want. Here is a
// really simple version.
function groupByGrade(data) {
return data.reduce(function(last, next) {
if (last[next.grade]) {
last[next.grade].push(next);
} else {
last[next.grade] = [next];
}
return last;
}, {});
}
// Get a unique list of the grades in the data to iterate over
function getGrades(data) {
return data.reduce(function(last, next) {
return !!~last.indexOf(next.grade) ? last : last + next.grade;
}, '').split('');
}
var rawData = [
{
grade: 'A',
type: 'Buy',
volume: 1000,
price: 10
}, {
grade: 'A',
type: 'Sell',
volume: 1200,
price: 10
}, {
grade: 'B',
type: 'Sell',
volume: 100,
price: 100
}
];
console.log(getGrades(rawData));
this.log = ko.observable(groupByGrade(rawData));
this.grades = ko.observableArray(getGrades(rawData));
}
ko.applyBindings(new testViewModel());