如何在绑定到客户端控件之前对SAPUI5 OData进行分组
How to group SAPUI5 OData before bind to control at client side?
我有一个JSON格式的odata列表:
var data = [
{"category" : "A", "value" : 1, "group" : "x"},
{"category" : "B", "value" : 2, "group" : "y"},
{"category" : "C", "value" : 3, "group" : "x"},
{"category" : "A", "value" : 4, "group" : "y"},
{"category" : "A", "value" : 5, "group" : "x"}
];
首先,我对group == x;
进行筛选,剩下的值是:
var data = [
{"category" : "A", "value" : 1, "group" : "x"},
{"category" : "C", "value" : 3, "group" : "x"},
{"category" : "A", "value" : 5, "group" : "x"}
];
现在我将按类别分组(在客户端)并汇总值,因此结果应该是:
var data = [
{"category" : "A", "value" : 6, },
{"category" : "C", "value" : 3, },
];
之后,我将模型绑定到一些SAPUI5控件。
但是分组部分似乎是不可能的。
有人知道这个问题的通用解决方案吗?
潜在用例:
var oDataset = new sap.viz.ui5.data.FlattenedDataset({
dimensions : [ {axis : 1, value : "{category}", name : "Category" } ],
measures : [ {value : "{value}", name : "Value" } ],
data : {
path : "/Data"
}
});
var oGraph = new sap.viz.ui5.Donut({
dataset : oDataset, // sap.viz.ui5.data.Dataset
});
下面的代码适合我。通过泛型绑定查询一对产品的Northwind Order_Details服务,映射减少返回的绑定并将每个订单的数量汇总为总销售数量,在柱状图中显示结果。
参见jsBin示例
sap.viz引入了Array.prototype.map和Array.prototype.reduce函数var sURI = 'http://services.odata.org/Northwind/Northwind.svc/';
var oDataModel = new sap.ui.model.odata.ODataModel(sURI, true);
oDataModel.setSizeLimit(10000);
var oJSONModel = new sap.ui.model.json.JSONModel({}, 'jmodel');
// handle list of contexts
var handler = function(oEvent) {
var mapCallback = function(oContext) {
var obj = {};
obj.ProductID = oContext.getObject().ProductID,
obj.Quantity = oContext.getObject().Quantity
return obj;
};
var reduceCallback = function(aPrev, oCurr) {
var aNext = aPrev;
var bFound = false;
aNext.forEach(function(item) {
if (item.ProductID === oCurr.ProductID) {
bFound = true;
item.Quantity += oCurr.Quantity;
}
})
if (bFound === false) {
aNext.push(oCurr);
}
return aNext;
};
//release handler
oBindings.detachChange(handler);
var aTotals = oEvent.oSource.getContexts().map(mapCallback).reduce(reduceCallback, []);
oJSONModel.setData({
'Order_Totals': aTotals
});
};
// Filter all orders by 3 products
var oFilter1 = new sap.ui.model.Filter("ProductID", sap.ui.model.FilterOperator.EQ, '1');
var oFilter2 = new sap.ui.model.Filter("ProductID", sap.ui.model.FilterOperator.EQ, '68');
var oFilter3 = new sap.ui.model.Filter("ProductID", sap.ui.model.FilterOperator.EQ, '11');
var aFilter = [oFilter1, oFilter2, oFilter3];
// Sort by ProductID
var oSorter = new sap.ui.model.Sorter("ProductID", false, true);
// Reduce the returned payload by nominating need fields
var oSelect = {
select: 'ProductID,Quantity'
}
var oBindings = oDataModel.bindList("/Order_Details", null, oSorter, aFilter, oSelect);
// call OData service and handle results
oBindings.attachChange(handler);
oBindings.getContexts();
var oDataset = new sap.viz.ui5.data.FlattenedDataset({
dimensions: [{
axis: 1,
name: 'ProductID',
value: "{ProductID}"
}],
measures: [{
name: 'Quantity Sold',
value: '{Quantity}'
}],
data: {
path: "/Order_Totals"
}
});
var oColumnChart = new sap.viz.ui5.Column({
width: "80%",
height: "400px",
plotArea: {
'colorPalette': d3.scale.category20().range()
},
title: {
visible: true,
text: 'Qutantity Sold by Product'
},
dataset: oDataset
});
oColumnChart.setModel(oJSONModel);
为您的最终结果,我写了一个代码。虽然它没有完全优化,但它工作得很好。
这是你的完整代码
var data = [
{"category" : "A", "value" : 1, "group" : "x"},
{"category" : "B", "value" : 2, "group" : "y"},
{"category" : "C", "value" : 3, "group" : "x"},
{"category" : "A", "value" : 4, "group" : "y"},
{"category" : "A", "value" : 5, "group" : "x"}
];
function groupBy( array , f )
{
var groups = {};
array.forEach( function( o )
{
if(o.group=="x")
{
var group = JSON.stringify( f(o) );
groups[group] = groups[group] || [];
groups[group].push( o );
}
});
return Object.keys(groups).map( function( group )
{
return groups[group];
})
}
var groupByGroup = groupBy(data, function(item)
{
return [item.group];
});
var groupByCategory = groupBy(groupByGroup[0], function(item)
{
return [item.category];
});
getData(groupByCategory);
function getData(groupByCategory)
{
var finalData=[];
for(var i=0;i< groupByCategory.length;i++)
{
var temp=0;
for(var j=0;j<groupByCategory[i].length;j++)
{
temp+=parseInt(groupByCategory[i][j].value);
}
finalData.push({"category":groupByCategory[i][0].category, "value":temp})
}
console.log(finalData);//final data is your required results
}
如果你想使用两个参数进行比较。假设你想按类别和组进行比较,那么在groupByGroup函数中你必须这样写
groupByCategory = groupBy(groupByGroup[0], function(item)
{
return [item.category,item.group];
})
并从groupBy函数中删除if(o.group=="x")。这个问题可以使用underscore.js轻松解决。有关帮助,请参阅这个问题
Underscore.js:集合中项目的总和
相关文章:
- 单击按钮即可在浏览器的新选项卡中打开 Sapui5 详细信息页面
- 自定义控件中的双向绑定在SAPUI5中不起作用
- 使用odata 4的jaydata 1.5和保存/更新数据时的错误
- 获取OData Binding的编辑数据
- sapui5对象头绑定
- SAPUI5中的分页符
- SAPUI5:如何获取行的索引
- BreezeJS / ODATA:只能对实体类型执行强制转换
- 在组件.js内加载客户 sapui5 库
- 使用 Grunt/Gulp 构建 SAPUI5 应用程序,并使用 ABAP Team Provider 部署 Eclip
- 如何使用 OData 查询选项按日期进行筛选
- 具有 OData 格式的 kendo 网格数据源 = json
- 在SAPUI5中引用自定义库会导致加载库时出现404
- SAPUI5 和 OData 服务的动态 URL
- 如何刷新(重新加载)SAPUI5 oModel(oData)
- 如何在绑定到客户端控件之前对SAPUI5 OData进行分组
- SAPUI5创建带有日期的OData实体——生成以CX_SXML_PARSE_ERROR结束的错误请求负载
- SAPUI5深度插入来自OData V2模型上Kapsel离线应用程序
- 试图在SAPUI5中实现对oData的异步读取调用
- 如何在sapui5中将OData模型转换为entityset