OpenUI5:数据在哪里,由sap.ui.model.odata.v2.ODataModel()加载?

时间:2017-01-04 13:57:00

标签: odata sapui5

我一直在谷歌搜索和测试几天没有成功。如果有人可以给我一个指示我指向正确方向的提示,那么我将非常感激。

我的目标是什么:从OData服务获取一些数据并在UI5 oTable中显示。稍后,我将不得不进行CRUD操作,但目前的目的只是成功显示数据。

到目前为止我得到了什么:我有一个MVC项目。我创建了一个OpenUI5Controller.cs,其目的是表示一个ODataService:

public class OpenUI5Controller : Controller
{
    private MyEntities myEntities = new MyEntities();

    public JsonResult GetAllContragents()
    {
        try
        {
            IQueryable<Contragent> contragents = myEntities.Contragent.OrderBy(x => x.Code);

            // for now, take the first 100 only
            contragents = contragents.Take(100);

            var jsonData = new
            {
                rows = contragents.ToList()
                //rows = "123"
            };

            var res = Json(jsonData, JsonRequestBehavior.AllowGet);
            return res;
        }
        catch (Exception e)
        {
            LoggingService.WriteLog("Error in OpenUI5Controller.GetAllContragents()", e);
            return null;
        }
    }
}

之后,我尝试使用这样的数据:

var oModel = new sap.ui.model.odata.v2.ODataModel('/OpenUI5/GetAllContragents', {
            //maxDataServiceVersion: '2.0',
            json: true,
            skipMetadataAnnotationParsing: true,
            // none of those callbacks is ever triggered, even the requestFailed...!?
            requestSent: function (a, b, c) {
                debugger;

                var trgrwg = oModel.getData();
                var vfewgvfewgv = oModel.getProperty('/');
                var vfewgvfewgv2 = oModel.getProperty('/rows');
                var vfewgvfewgv3 = oModel.getProperty('rows');
            },
            requestFailed: function (a, b, c) {
                debugger;

                var trgrwg = oModel.getData();
                var vfewgvfewgv = oModel.getProperty('/');
                var vfewgvfewgv2 = oModel.getProperty('/rows');
                var vfewgvfewgv3 = oModel.getProperty('rows');
            },
            requestCompleted: function (a, b, c) {
                debugger;

                var trgrwg = oModel.getData();
                var vfewgvfewgv = oModel.getProperty('/');
                var vfewgvfewgv2 = oModel.getProperty('/rows');
                var vfewgvfewgv3 = oModel.getProperty('rows');
            },
            batchRequestCompleted: function (a, b, c) {
                debugger;

                var trgrwg = oModel.getData();
                var vfewgvfewgv = oModel.getProperty('/');
                var vfewgvfewgv2 = oModel.getProperty('/rows');
                var vfewgvfewgv3 = oModel.getProperty('rows');
            },
            useBatch : false
        });

var trgrwg = oModel.getData();
        var vfewgvfewgv = oModel.getProperty('/');
        var vfewgvfewgv2 = oModel.getProperty('/rows');
        var vfewgvfewgv3 = oModel.getProperty('rows');
        var vfewgvfewgv4 = oModel.getProperty('contragents');
        var vfewgvfewgv5 = oModel.getProperty('/contragents');
        var vfewgvfewgv6 = oModel.getProperty('Contragents');
        var vfewgvfewgv7 = oModel.getProperty('/Contragents');
debugger;

在此断点处停止时,我在Chrome开发者工具中看到了这一点: enter image description here

走得更远,我来到this并尝试阅读()那些会员:

oModel.read('/Contragents', {
            success: function (event) {
                debugger;
                // event.root I guess should be the received data as jsonString

                // As I guess, I will have to get it and give it to oModel.oData manually, or am I wrong? I guess this would cause update(), delete()... calls to fail later on. Anyways...

                sap.ui.getCore().setModel(oModel); // https://archive.sap.com/discussions/thread/3746588 - seems not to work like this
                if (withJsonModel !== true) {               https://help.sap.com/saphelp_uiaddon20/helpdata/en/12/32241b99d7437ba3614698d53dfa4b/content.htm
                    oTable.setModel(oModel);
                    oTable.bindRows("/");
                    //oTable.bindRows("/rows");
                    oTable.placeAt('tblContragents', "only");
                }
            },
            error: function (event) {
                debugger;
            }
        });

在这里,既没有成功也没有错误回调被触发。

在这次read()尝试之后,我又来了:

var trgrwg = oModel.getData();
        var vfewgvfewgv = oModel.getProperty('/');
        var vfewgvfewgv2 = oModel.getProperty('/rows');
        var vfewgvfewgv3 = oModel.getProperty('rows');
        var vfewgvfewgv4 = oModel.getProperty('contragents');
        var vfewgvfewgv5 = oModel.getProperty('/contragents');
        var vfewgvfewgv6 = oModel.getProperty('Contragents');
        var vfewgvfewgv7 = oModel.getProperty('/Contragents');

我看到了这个: enter image description here

之后,我有oTable = new sap.ui.table.Table(...);

最后,我试试这个:

sap.ui.getCore().setModel(oModel);
        //oTable.setModel(oModel); // or maybe should be this one directly?
        oTable.bindRows("/Contragents");
        oTable.placeAt('tblContragents', "only");

结果,我得到一张空桌子。 我想我应该告诉你我在Fiddler中看到的内容:我看到了这个请求:1 200 HTTP localhost:55714 / OpenUI5 / GetAllContragents / $ metadata 因此,在响应部分的TextView中,我将数据视为json,我需要在表中显示。

如何使其工作并在表格中显示数据?

从02.02.2017编辑:我有1%的进度。经过一些越来越多的测试和谷歌搜索,我决定尝试这样。

首先,在一段时间之前(真的不记得何时),在看到a good example for OdataServices后,我决定创建一个像这样的专用控制器:

public class ContragentsController : ODataController
{
    private MyEntities db = new MyEntities();


    //public System.Web.Mvc.JsonResult GetContragents()
    public string GetContragents()
    {
        try
        {
            IQueryable<Contragent> contragents = db.Contragent.OrderBy(x => x.Code);

            // for now, give me first 100
            contragents = contragents.Take(100);

            var jsSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();

            var rows = jsSerializer.Serialize(contragents.ToList());

            //var jsonData = new
            //{
            //    rows = model
            //};

            //var res = new System.Web.Mvc.JsonResult();
            //res.Data = jsonData;
            //res.JsonRequestBehavior = System.Web.Mvc.JsonRequestBehavior.AllowGet;

            return rows;
        }
        catch (Exception e)
        {
            //...some errorLogging
            return null;
        }
    }

之后,我将调用更改为ODataModel():

var oModel = new sap.ui.model.odata.v2.ODataModel(BASE_HREF + 'odata/', {
            //maxDataServiceVersion: '2.0',
            json: true,
            skipMetadataAnnotationParsing: true,
            // those callbacks still do not get called at all
            requestSent: function (a, b, c) {
                debugger;

                var trgrwg = oModel.getData();
                var vfewgvfewgv = oModel.getProperty('/');
                var vfewgvfewgv2 = oModel.getProperty('/rows');
                var vfewgvfewgv3 = oModel.getProperty('rows');
            },
            requestFailed: function (a, b, c) {
                debugger;

                var trgrwg = oModel.getData();
                var vfewgvfewgv = oModel.getProperty('/');
                var vfewgvfewgv2 = oModel.getProperty('/rows');
                var vfewgvfewgv3 = oModel.getProperty('rows');
            },
            requestCompleted: function (a, b, c) {
                debugger;

                var trgrwg = oModel.getData();
                var vfewgvfewgv = oModel.getProperty('/');
                var vfewgvfewgv2 = oModel.getProperty('/rows');
                var vfewgvfewgv3 = oModel.getProperty('rows');
            },
            batchRequestCompleted: function (a, b, c) {
                debugger;

                var trgrwg = oModel.getData();
                var vfewgvfewgv = oModel.getProperty('/');
                var vfewgvfewgv2 = oModel.getProperty('/rows');
                var vfewgvfewgv3 = oModel.getProperty('rows');
            },
            useBatch : false
        });

整个戏剧是SapUI5在向odata / Contragents提出实际请求之前运行$元数据请求。正如在这种情况下预期的那样,我在Fiddler中看到,服务器404-s到该请求:http://localhost:55714/odata/Contragents/ $元数据并且它没有到达向Contragents发出请求的时刻。我知道,为了防止这个$元数据请求运行,我不得不在某处更改库的源代码,我不想这样做。所以在Fiddler的Composer中,我尝试了以下内容:localhost:55714 / odata / $ metadata,它返回了一些带有所需元数据的xml(可能确实很重要,但我还没有理解为什么)。下一步是修改对sap.ui.model.odata.v2.ODataModel()的调用;如上所示。事实上,最重要的是oModel.read('/ Contragents',{...});显示出生命迹象!现在,成功回调被调用并在event.root中我将这些contragents作为json字符串。 然后呢?我试过oModel.setData(JSON.parse(event.root));但它给了我这个错误: this error

另外,如果我设法以这种方式工作,我不太明白,oModel的CRUD方法是否有效? oModel.setData() - 从我玩JSONModel()时起就是我所熟悉的东西:

oModel = new sap.ui.model.json.JSONModel();
oModel.setData(dataForGrid); // this works like a charm

但是使用JSONModel()意味着,我不能使用sap.ui.model.odata.v2.ODataModel()的insert(),update()...方法,因为JSONModel();我没有提供它们,这是正常的,只要我通过标准的$ .ajax()调用获取dataForGrid。

edit2:在调试时,我注意到,方法ContragentsController.GetContragents();被调用两次,在控制台中,我看到此错误消息: this error message

edit3:关注the good example for ODataService后,我向控制器添加了一个“选择”方法,如下所示:

// GET: odata/Contragents(5)
    [EnableQuery]
    public SingleResult<Contragent> GetContragents([FromODataUri] string key)
    {
        return SingleResult.Create(db.Contragent.Where(contragent => contragent.Code == key));
    }

在Fiddler中,它是404-s并且根本不会被调用,无论我是这样写的:http://localhost:55714/Contragents(2)还是这样:http://localhost:55714/odata/Contragents(2)

几分钟后,我有几个百分点的进步。我在教程中看得更近了,我注意到了一些东西,这让我改变了“选择”方法:

// GET: odata/Contragents(5)
    [EnableQuery]
    public SingleResult<Contragent> Get([FromODataUri] string key)
    {
        return SingleResult.Create(db.Contragent.Where(contragent => contragent.Code == key));
    }

现在,当我撰写此请求时:http://localhost:55714/odata/Contragents(2),它现在不是404,而是406不可接受。我前段时间遇到过这个错误代码,我不明白它是什么原因以及它与ODataServices有什么关系。

我只是提醒自己406意味着什么,结果是控制器上的每个方法都必须以字符串形式返回json结果。因为,SapUI5将Accept-Type设置为“application / json”。

0 个答案:

没有答案