web-dev-qa-db-ja.com

XMLビューで展開されたコレクションからOData $ countをバインドする方法

これは基本的な質問かもしれませんが、XMLビューでODataカウントをバインドするのに問題があります。

次の例では、ODataモデルの製品数をバインドします。

<List items="{/Categories}"} >  
  <ObjectListItem
    title="{CategoryName}"
    number="{path : 'Products/$count'}"
    numberUnit="Products"/>
</List>

各カテゴリは、次のように各カテゴリの製品数を表示する必要があります

/Categories(1)/Products/$count
/Categories(2)/Products/$count
13
c_y

私はそれが現在可能であるとは思いません-$ countはODataクエリオプションです。ODataListBindingで同等のものは長さです。たとえば、Products.lengthはそれにバインドする方法を考えることができません。

フォーマッターを使用していくつかの方法でカウントを達成できます

オプション1-最も単純な、製品の合計数を読み取るリストバインディングを作成します。同期呼び出しを行い、$ countのみを返します

function productCount(oValue) {
    //return the number of products linked to Category // sync call only to get $count
    if (oValue) {
        var sPath = this.getBindingContext().getPath() + '/Products';
        var oBindings = this.getModel().bindList(sPath);
        return oBindings.getLength();
    }
};

<List items="{/Categories}"} >  
 <ObjectListItem 
    title="{CategoryName}"
    number="{path : 'CategoryName',formatter:'productCount'}"
    numberUnit="Products" 
 </ObjectListItem>
</List>

オプション2-展開を使用して非常に小さなデータセットを返します。この場合は、CategoryNameとProductIDのみです。ここでの警告は、完全なリストを取得するためにテーブルページングをバイパスする必要があるかどうかです。

function productCount(oValue) {
    //read the number of products returned
    if (oValue) {
        return oValue.length;
    }
};

<List items="{/Categories,parameters:{expand:'Products', select:'CategoryName,Products/ProductID'}}">  
 <ObjectListItem 
    title="{CategoryName}"
    number="{path : 'Products',formatter:'productCount'}"
    numberUnit="Products" 
 </ObjectListItem>
</List>
7
Jasper_07

同様の問題がありました。私は自分のソリューションに興奮していませんが、式バインディングを使用しており、別個のフォーマッターを必要とせずに機能します。

<List items="{/Categories}"} >  
  <ObjectListItem 
    title="{CategoryName}"
    number="{= ${Products}.length }"
    numberUnit="Products" />
</List>

@ Jasper_07のように、エキスパンドにProductsを含める必要がありますが、戻ってくるデータのほとんどを無視しています。

12
Erik Allen

まあ..同じ要件が正確にあり、oDataからすべてのProductsコレクションをロードするため、@ jasperからの賢い解決策を実行したくありませんでしたサービス。

これは私がそれを解決する方法でした:

見る

  1. コントローラを使用する
  2. リストにIDを与える
  3. リストの updateFinished イベントで関数を使用します。
<mvc:View 
  controllerName="view.Root"
  xmlns:mvc="sap.ui.core.mvc"
  xmlns="sap.m"
>
  <List id="list"
    headerText="Categories"
    items="{/Categories}"
    growing="true"
    growingThreshold="4"
    growingScrollToLoad="true"
    updateFinished=".countProducts"
  >
    <ObjectListItem
      title="{description}"
      numberUnit="Products"
    />
  </List>
</mvc:View>

コントローラ

  1. countProducts関数を実装する
  2. JQueryを使用して各リストアイテムの$ countをリクエストします-モデルのサービスURLとアイテムのバインディングコンテキストを連結したURLが生成されることに注意してください
  3. JQueryは非同期要求を使用するため、最初の応答が得られるまでに、forは完了します。したがって、 [〜#〜] iife [〜#〜] を使用して、最後のリスト項目だけをAJAX応答で埋めることを回避できます。
countProducts: function(e){
  var m = sap.ui.getCore().getModel();
  var items = this.byId("list").getItems();    
  for (var item_index = 0; item_index < items.length; item_index++) {
    var item = items[item_index];
    (function(_item) {
      $.get(
        m.sServiceUrl + _item.getBindingContextPath() + "/Categorias/$count",
        function(count) {
          _item.setNumber(count);
        }
      );
    })(item);
  }
}
3
fabiopagoti

同様の問題について、Manifest.json、Component.js、Controller.jsを使用する別のソリューションを用意しました。

最初に、App.view.xmlでIDを定義しました。次に例を示します。

<Title id="titleId" text="" level="H2"/>

その後、特にManifest.jsonを確認します。

{
"sap.app": {
    "dataSources": {
        "AXXX": {
            "uri": "https://cors-anywhere.herokuapp.com/https://services.odata.org/Northwind/Northwind.svc/",

次に、Componente.jsのinit:function()に次のように配置します。

var oDataServiceUrl = this.getMetadata().getManifestEntry("sap.app").dataSources["AXXX"].uri;
console.log("oDataServiceUrl = ", oDataServiceUrl);
localStorage.setItem('oDataServiceUrl', oDataServiceUrl); 

このコードはManifest.jsonを読み取り、AXXXと呼ばれるoDataServiceへのURLを取得します。

Finnalyでは、App Controllerで次のような関数を1つ作成しました。

countCustomersInAXXX : function (oEvent) {

    var suffix = 'Customers/$count';
    var oDataServiceUrl = localStorage.getItem('oDataServiceUrl');
    var oDataServiceUri = oDataServiceUrl.concat(suffix);
    console.log('App.controller.js: oDataServiceUri', oDataServiceUri);

    var count = $.ajax({type: "GET", url: oDataServiceUri, async: false}).responseText;
    console.log('App.controller.js: countCustomersInAXXX:' , count);

    this.getView().byId("titleId").setText(count);
}

このコードは、Customersの数量を取得し、titleIdに値を設定します。

このプロセスを開始するには、ボタンまたは1つのイベントを使用できます。私の場合、このTableプロパティを使用します。

updateFinished="countCustomersInAXXX"
0