<!DOCTYPE html>
<html style="height: 100%;">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <title>Demo</title>
    <!-- Below settings are for testing and demo purposes only. -->
    <!-- In production: use a specific UI5 version, not the "latest" one. -->
    <script>
      globalThis["sap-ui-config"] = {
        securityTokenHandlers: [ // Only for the sample OData V4 service
          () => new Promise(resolve => resolve({ "X-CSRF-Token": "42" })),
        ]
      };
    </script>
    <script defer id="sap-ui-bootstrap"
      src="https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js"
      data-sap-ui-oninit="module:sap/ui/core/ComponentSupport"
      data-sap-ui-async="true"
      data-sap-ui-theme="sap_horizon"
      data-sap-ui-compatversion="edge"
      data-sap-ui-excludejquerycompat="true"
      data-sap-ui-resourceroots='{ "demo": "./" }'
      data-sap-ui-xx-waitfortheme="init"
    ></script>
  </head>
  <body id="content" class="sapUiBody">
    <div data-sap-ui-component
      data-id="rootComponentContainer"
      data-name="demo"
      data-settings='{ "id": "rootComponent" }'
      data-height="100%"
      style="height: 100%;"
    ></div>
  </body>
</html>
sap.ui.define([
  "sap/ui/core/UIComponent",
  "sap/ui/core/ComponentSupport",//https://github.com/SAP/ui5-tooling/issues/381
], function(UIComponent) {
  "use strict";

  return UIComponent.extend("demo.Component", {
    metadata: {
      interfaces: [
        "sap.ui.core.IAsyncContentCreation",
      ],
      manifest: "json",
    },

  });
});
{
  "_version": "1.35.0",
  "start_url": "index.html",
  "sap.app": {
    "id": "demo",
    "type": "application",
    "title": "Demo",
    "description": "Sample Code",
    "applicationVersion": {
      "version": "1.0.0"
    },
    "dataSources": {
      "myDataSource": {
        "uri": "https://services.odata.org/TripPinRESTierService/(S(e0fqh2pbbloxj0wjkflvewqt))/",
        "type": "OData",
        "settings": {
          "odataVersion": "4.0"
        },
        "_NOTE": "This sample OData service is CORS enabled (See https://github.com/OData/ODataSamples/issues/29). Your OData service might need a reverse proxy server if it doesn't suppprt CORS."
      }
    }
  },
  "sap.ui": {
    "technology": "UI5",
    "deviceTypes": {
      "desktop": true,
      "tablet": true,
      "phone": true
    }
  },
  "sap.ui5": {
    "handleValidation": true,
    "dependencies": {
      "minUI5Version": "1.95.0",
      "libs": {
        "sap.ui.core": {},
        "sap.m": {}
      }
    },
    "contentDensities": {
      "compact": true,
      "cozy": true
    },
    "models": {
      "": {
        "dataSource": "myDataSource",
        "settings": {
          "autoExpandSelect": true,
          "operationMode": "Server",
          "synchronizationMode": "None",
          "earlyRequests": true
        },
        "preload": true
      }
    },
    "rootView": {
      "viewName": "demo.view.Root",
      "id": "rootView",
      "type": "XML",
      "async": true,
      "height": "100%"
    }
  }
}
<mvc:View controllerName="demo.controller.Root"
  xmlns:mvc="sap.ui.core.mvc"
  xmlns="sap.m"
  displayBlock="true"
>
  <App autoFocus="false">
    <Page showHeader="false" class="sapUiResponsiveContentPadding">
      <!-- Sample sap.m.ListBase control -->
      <Table id="table" headerText="OData V4 Trippin People">
        <columns>
          <Column>
            <Text text="First Name" />
          </Column>
          <Column>
            <Text text="Last Name" />
          </Column>
        </columns>
        <dependents>
          <ColumnListItem id="itemToCopy">
            <Text text="{FirstName}" />
            <Text text="{LastName}" />
          </ColumnListItem>
        </dependents>
      </Table>
    </Page>
  </App>
</mvc:View>
sap.ui.define([
  "sap/ui/core/mvc/Controller",
  "sap/ui/core/CustomData", // dependency for the .data API
], function(Controller) {
  "use strict";

  /**
   * This is a small sample. Adjust according to your project
   */
  return Controller.extend("demo.controller.Root", {
    onInit: function() {
      this.startList(this.byId("table"), 0, 5, {
        path: "/People",
        template: this.byId("itemToCopy"),
        templateShareable: true,
        filters: [/*...*/],
        parameters: {
          $count: true,
          // ...
        },
      });
    },

    startList: function(listBase, $skip, $top, restInfo) {
      let startIndex = $skip;
      let length = $top;
      let totalSize;
      (function repeat(that) {
        const bindingInfo = Object.assign({ startIndex, length }, restInfo);
        listBase.bindItems(bindingInfo);
        listBase.data("repeater", event => {
          totalSize = event.getParameter("total"); // $count value e.g. 20
          startIndex += $top;
          startIndex = startIndex < totalSize ? startIndex : 0;
          that._timeoutID = setTimeout(() => repeat(that), 2000);
        }).attachEventOnce("updateFinished", listBase.data("repeater"), that);
      })(this);
    },

    stopList: function(listBase) {
      if (!listBase) {
        sap.ui.require(["sap/base/Log"], Log => Log.error("Which list??"));
        return;
      }
      clearInterval(this._timeoutID);
      listBase.detachEvent("updateFinished", listBase.data("repeater"), this);
    },

    onExit: function() {
      this.stopList(this.byId("table"));
      this.byId("itemToCopy").destroy();
    },

  });
});