1

I try to figure out how I can bind data to sap.m.CustomListItem during onInit of my controller. I tried a lot but nothing seems to fit. It looks so easy on the examples from the UI5 Demo Kit.

<mvc:View
  height="100%"
  controllerName="sap.ui.demo.toolpageapp.controller.settings.MasterSettings"
  xmlns:mvc="sap.ui.core.mvc"
  xmlns="sap.m">
  <List>
    <items items="{folder>objects}">
      <CustomListItem items="{folder>/object/properties/cmis:name/value}">
        <Link id="text6"
          maxLines="0"
          text="{folder>/object/properties/['cmis:objectId']/displayName}" />
        <OverflowToolbar id="otbFooter">
          <Button type="Accept" text="Accept">
            <layoutData>
              <OverflowToolbarLayoutData priority="NeverOverflow" />
            </layoutData>
          </Button>
          <Button type="Reject" text="Reject">
            <layoutData>
              <OverflowToolbarLayoutData priority="NeverOverflow" />
            </layoutData>
          </Button>
        </OverflowToolbar>
        <SearchField/>
      </CustomListItem>
    </items>
  </List>
</mvc:View>
sap.ui.define([
  "sap/ui/demo/toolpageapp/controller/BaseController",
  "sap/m/MessageToast",
  "sap/ui/model/json/JSONModel",
  "sap/ui/demo/toolpageapp/model/formatter"
], function(BaseController, MessageToast, JSONModel, formatter) {
  "use strict";
  var cmisRootFolder;
  var children;

  return BaseController.extend("sap.ui.demo.toolpageapp.controller.settings.MasterSettings", {
    formatter: formatter,
    onInit: function() {
      getCMISFolderStructure();
      var oModel = new JSONModel(cmisRootFolder);
      this.setModel(oModel, "folder");
      console.log(oModel);

      function processRootFolder(data) {
        cmisRootFolder = data;
      }

      function getCMISFolderStructure() {
        $.ajaxSetup({
          headers: {
            "Access-Control-Allow-Origin": "*"
          }
        });
        const session = new cmis.createSession("http://localhost:8080/myTest/browser");
        session.setCredentials('test', 'test').getFolderTree("rfHN5c3RlbXwxfHJlcG8xfC8=", 2, {
          request: {
            async: false,
            success: processRootFolder,
            error: function(e) {
              if (e)
                console.log(false, "Error during the request: " + e);
              else
                console.log(false, "Error during the request: " + e);
            }
          }
        })
      }
    },

    onMasterPressed: function(oEvent) {
      var oContext = oEvent.getParameter("listItem").getBindingContext("side");
      var sPath = oContext.getPath() + "/selected";
      oContext.getModel().setProperty(sPath, true);
      var sSelectedMasterElement = oContext.getProperty("title");
      var sKey = oContext.getProperty("key");
      switch (sSelectedMasterElement) {
        case "System Settings": {
          this.getRouter().navTo(sKey);
          break;
        }
        default: {
          MessageToast.show(sSelectedMasterElement + " was pressed");
          break;
        }
      }
    },

    onToggleOpenState: function(oEvent) {
      var iItemIndex = oEvent.getParameter("itemIndex");
      var oItemContext = oEvent.getParameter("itemContext");
      var bExpanded = oEvent.getParameter("expanded");
      MessageToast.show("Item index: " + iItemIndex +
        "\nItem context (path): " + oItemContext +
        "\nExpanded: " + bExpanded, {
          duration: 5000,
          width: "auto"
        });
      var oTree = this.byId("Tree");
      var oModel = this.getView().getModel();
      var sPath = oItemContext.getPath();
      var bChildIsDummyNode = oModel.getProperty(sPath + "/nodes/0").dummy === true;
      if (bExpanded && bChildIsDummyNode) {
        this.loadData(oModel, sPath, oTree.getItems()[iItemIndex].getLevel());
      }
    },

    loadData: function(oModel, sPath, iLevel) {
      var oTree = this.byId("Tree");

      function processRootFolder(data) {
        cmisRootFolder = data;
      }
      $.ajaxSetup({
        headers: {
          "Access-Control-Allow-Origin": "*"
        }
      });
      const session = new cmis.createSession("http://localhost:8080/myTest/browser");
      session.setCredentials('test', 'test').getFolderTree("rfHN5c3RlbXwxfHJlcG8xfC8=", 2, {
          request: {
            async: false,
            success: processRootFolder,
            error: function(e) {
              if (e)
                console.log(false, "Error during the request: " + e);
              else
                console.log(false, "Error during the request: " + e);
            }
          }
        }),
        // In this example we are just pretending to load data from the backend.
        //oTree.setBusy(true);
        setTimeout(function() {
          var aNewNodes = [cmisRootFolder];
          oModel.setProperty(sPath ? sPath + "/nodes" : "/", aNewNodes);
          //oTree.setBusy(false);
          console.log(oModel);
        }, 2000);
    },

    onSavePressed: function() {
      MessageToast.show("Save was pressed");
    },

    onCancelPressed: function() {
      MessageToast.show("Cancel was pressed");
    },

    onNavButtonPress: function() {
      this.getOwnerComponent().myNavBack();
    }
  });
});

I found an example in the internet and it looked like it's exactly that what I need. And that is what you see in the code example above. But it does not work.

1
  • Off-topic but async: false (in controller) really needs to be avoided. Especially if you already have a dedicated success handler. Sending synchronous XHR freezes the UI (main) thread of the browser which results in a bad UX. Commented Apr 24, 2020 at 10:02

1 Answer 1

1

Where did you find the code snippets? There are too many errors.

items="{folder>objects}"

The binding paths in the view need to be corrected. According to your data, it should be items="{folder>/objects}" i.e. absolute binding path (Slash after > is missing).

Documentation: Binding Path


<items items="{folder>objects}">

Named aggregation nodes cannot have aggregation binding. Only ManagedObjects (Controls) support binding properties, aggregations, and contexts. Move the aggregation binding to the <List>.


<CustomListItem items="{...}">

sap.m.CustomListItem doesn't have items-aggregation at all.


text="{folder>/object/properties/['cmis:objectId']/displayName}"

According to your data, properties is not an array but an object, so you cannot apply xpath-like syntax such as /['cmis:objectId']/. Also, you can make use of the context that was passed to the children (resulted from aggregation binding). No need to assign an absolute binding path.
Remove the first slash after > to make it relative.


TL;DR

Try with:

<List items="{folder>/objects}">
  <CustomListItem>
    <Link text="{folder>properties/cmis:objectId/displayName}" />
    <!-- ... -->
  </CustomListItem>
</List>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.