通过SAPUI5中的批处理操作更新oData

时间:2014-11-07 18:23:53

标签: odata batch-processing sapui5

我在下面列出了以下代码:

oTable = sap.ui.getCore().byId('tableID');
var index = oTable.getSelectedIndex();

if (index > -1) {
    var currentRowContext = oTable.getContextByIndex(index);
    var model = oTable.getModel();
    var name = model.getProperty("NAME", currentRowContext);

    var phase = model.getProperty("PHASE", currentRowContext);
    var originalPhase = Phase;
    var sequence;

    var batchChanges = [];

    jQuery.ajax({
        type: "GET",
        contentType: "application/json",
        url: "http://urlpathforxsodata/customer.xsodata/TOOL/?$filter=NAME eq '" + name + "'",
        dataType: "json",
        async: false,
        success: function(data, textStatus, jqXHR) {

            // After processing while loop, index will be the
            // first non-frozen record
            while (originalPhase == phase) {
                index = index + 1;
                phase = data.d.results[index].PHASE;
            }

            for (var i = 0; i < index; i++) {
                var frozenFlag = data.d.results[i].FROZEN_FLG;
                if (frozenFlag != 1) {
                    sequence = data.d.results[i].SEQUENCE;
                    var entry = {
                        NAME: name,
                        SEQUENCE: sequence,
                        FROZEN_FLG: 1,
                    };

                    batchChanges.push(model.createBatchOperation(
                        "/TOOL(NAME='" + name + "',SEQUENCE=" + sequence + ")",
                        "PUT",
                        entry)
                    );
                }
            }

            model.addBatchChangeOperations(batchChanges);

            // submit changes and refresh the
            // table and display message
            model.submitBatch(function(data) {
                model.refresh();
            });
        }
    });
}

代码的开头部分是我已经验证的业务逻辑,用于确定我想要更新哪些行。我使用Ajax返回一个完全如表中所示的数据集(表不能被过滤或排序,因此索引将匹配)。我的问题与我正在进行的录入和批量通话有关。它无法正常工作,我收到了以下订单:

POST /FiringOrder.xsodata/TOOL /Services/customer.xsodata/$batch

  

&#34; 2014-11-06 11:26:02出现以下问题:HTTP请求失败400,错误请求,{&#34;错误&#34;:{&#34;代码&#34;:& #34;&#34;,&#34;消息&#34;:{&#34; lang&#34;:&#34; en-US&#34;,&#34;值&#34;:&#34 ;位置29的资源路径中的语法错误。&#34;}}} - &#34;树液-UI-core.js:80

     

&#34; 2014-11-06 11:26:02出现以下问题:HTTP请求失败400,错误请求,{&#34;错误&#34;:{&#34;代码&#34;:& #34;&#34;,&#34;消息&#34;:{&#34; lang&#34;:&#34; en-US&#34;,&#34;值&#34;:&#34 ;位置29的资源路径中的语法错误。&#34;}}} - &#34;

三个问题:

  1. 有没有更好的方法来调试http请求错误? (对不起,我真的很新!)
  2. 我格式化批次或输入错误了吗?我对使用参数传递的URL路径有疑问(名称和序列都是记录的键)以及我是否应该使用PUT进行更新。尝试MERGE除了立即给我一个区别错误并且错误信息不可用之外什么都不做。
  3. 最后但并非最不重要的是,所有这些逻辑都在我的控制器中。这是正确的还是应该在服务器上完成这种逻辑?

3 个答案:

答案 0 :(得分:2)

首先,它很难阅读您的代码:-)请查看此文档:
SAPUI5 - Batch Operations - how to do it right?

约1)你得到的错误信息是来自后端(SAP)的响应,它与你在transaction / IWFND / ERROR_LOG中得到的错误相同..在我看来这个信息已经足够了,BAD REQUEST说你的请求(POST)格式错误,您的逻辑在后端引发转储 - 有关详细信息,请检查后端。我认为通过从AJAX记录成功/错误消息的方式是调试http请求最常见的。

约2)我想是的,首先它说的是错误的请求(检查错误日志的后端)。否则你是否在控制器中初始化你的模型? Odata POSTing仅适用于Odata模型,目前您正试图将其称为表模型?我认为这不起作用,所以我建议保持逻辑直到&#34; model.addBatchChangeOperations(batchChanges);&#34;提交然后:

onInit : function() { // in controller
    // register the central service (for create/update/other operations)
    var sServiceUrl = "/sap/opu/odata/sap/YOUR_SRV/";
    var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl, true);
    sap.ui.getCore().setModel(oModel);
}

然后查看或提交时:

var oModel = sap.ui.getCore().getModel(); // ensure that you did not overwrite your 
                                          // model locally!! with some JSON model for example
oModel.addBatchChangeOperations(batchChanges);
oModel.setUseBatch(true);
oModel.submitBatch();

约3)如果你在本地(在前端)使用你要发布的数据,我认为控制器很好(imho)。

进一步评论:据我所知,你想在表格中重新加载数据,我认为通过发布数据,获取结果,然后将数据重新绑定到表格,可以更轻松地完成这项工作。

问候,zY

答案 1 :(得分:2)

如果你的模型是OData V2 Model,这将是一个不同的野兽。如果模型属于这种情况,则控制器的编程流程必须:

  1. 确保oModel.setUseBatch参数为true,
  2. 发出一系列请求,为其分配GroupID或ChangeSetID
  3. 最后使用oModel.submitChanges()方法在一个$ batch请求中提交所有请求。
  4. 我在回复SAP SCN thread时详细说明了这一点。我将继续粘贴一个正在运行的JS Controller方法的代码片段,该方法向SAP服务器提交一系列PUT请求的$ batch请求。

    var _postPaymentClosure = function(itemsTable){  
    return function(oEvent){  
        var source = oEvent.getSource();  
        var oModel = source.getModel();  
        oModel.setUseBatch(true); //if this is not already done  
        var scopeKey = paymentScopeRBG.getSelectedIndex();  
        var items = itemsTable.getItems();  
        var changeSetId = "foo";  
    
        //Prep header-level group/changeset params  
        var mParameters = {  
            "groupId": changeSetId,  
            "changeSetId": changeSetId  
        }; //I'm using both...maybe one isn't needed??  
     //Loop through the items, updating each  
        var row;  
        var itemObject;  
        var context;  
        for(var i = 0; i < items.length; i++){  
            row = items[i];  
            context = row.getBindingContext();  
            itemObject = context.getObject();  
    
            //Do whatever updates to the JSON you want here....  
            itemObject.PaymentCardID = "bar";  
    
          //Then execute the v2 model's Update function  
           oModel.update(context.sPath, itemObject, mParameters);  
        }  
    
    //Finally, submit all the batch changes  
        oModel.submitChanges(mParameters);  
        };
    };  
    

答案 2 :(得分:0)

在我的情况下,我需要在循环中添加行oModel.setRefreshAfterChange(true);

var mParameters = {
            groupId :"batchCreate"
         }
for (var i = 0; i < data.length; i++) {
        sEntry.Matnr = data[i].Matnr;
        sEntry.Bbynr = data[i].Bbynr;
        sEntry.Prio = data[i].Prio;

        oModel.update("/Data1Set('"+data[i].Bbynr+"')", sEntry, mParameters);

        oModel.submitChanges(mParameters);
        oModel.setRefreshAfterChange(true);
        }

    },