docs

Meta Model for OData V4

Each OData V4 model offers access via getMetaModel to a corresponding metadata model sap.ui.model.odata.v4.ODataMetaModel, which is read-only and offers access to OData V4 metadata in a streamlined JSON format (see links under Related Information for more details). Only one-time bindings are supported by this model because the metadata is immutable.


Synchronous vs. Asynchronous Access

Access to metadata is basically asynchronous (e.g. requestObject) to allow for dynamic loading of metadata. There is also a corresponding method for synchronous access (e.g. getObject) which returns undefined if metadata is not yet available. It should only be used in situations where metadata has already been loaded asynchronously before. Loading happens individually for each document, i.e. each $metadata document is loaded and processed as a whole and is available thereafter. Includes and references to other $metadata documents are not supported, only the service root’s initial $metadata document can be used.


Path Syntax

The requestObject API documentation in the Demo Kit explains how metadata is accessed and the supported path syntax in great detail. The basic idea is that every path described in the specification OData Version 4.0 Part 3: Common Schema Definition Language, 14.2.1 Attribute Target is a valid absolute path within the metadata model if a leading slash is added; for example "/" + "MySchema.MyEntityContainer/MyEntitySet/MyComplexProperty/MyNavigationProperty". For more information, see the requestObject API documentation in the Demo Kit.


Annotations

The main API for both programmatic access from JavaScript and declarative access from XML templating is sap.ui.model.odata.v4.ODataMetaModel#getObject. It works together with sap.ui.model.odata.v4.ODataMetaModel#resolve (for <template:with>) and sap.ui.model.odata.v4.ODataMetaModel#bindList (for <template:repeat>) in order to provide convenient access to annotations, inline as well as external targeting.

The OData meta model knows how to follow “14.2.1 Attribute Target” described in specification “OData Version 4.0 Part 3: Common Schema Definition Language” as well as “14.5.2 Expression edm:AnnotationPath”, “14.5.11 Expression edm:NavigationPropertyPath”, “14.5.12 Expression edm:Path”, and “14.5.13 Expression edm:PropertyPath”.

XML Templating still works the same as for V2, with some slight changes as outlined below:

Example of an OData V4 XML template:

<mvc:View
        template:require="{AnnotationHelper : 'sap/ui/model/odata/v4/AnnotationHelper'}"
        xmlns="sap.m"
        xmlns:template="http://schemas.sap.com/sapui5/extension/sap.ui.core.template/1">
    <template:alias name="format" value="AnnotationHelper.format">
    <template:alias name="value" value="AnnotationHelper.value">
        <template:with path="meta>/BusinessPartnerList/" var="entityType">
          <template:with path="entityType>@com.sap.vocabularies.UI.v1.LineItem" var="lineItem">
            <Table headerText="Business Partners"
              items="{path : '/BusinessPartnerList', length : 5}">
              <columns>
                <template:repeat list="{lineItem>}" var="field">
                  <Column>
                    <template:if test="{field>Label}">
                      <template:then>
                        <Label design="{:= ${field>@com.sap.vocabularies.UI.v1.Importance/$EnumMember}
                          === 'com.sap.vocabularies.UI.v1.ImportanceType/High' ? 'Bold' : 'Standard'}"
                          text="{field>Label}"/>
                      </template:then>
                      <template:else>
                        <Text text="{field>Value/$Path@com.sap.vocabularies.Common.v1.Label}"/>
                      </template:else>
                    </template:if>
                  </Column>
                </template:repeat>
              </columns>
              <items>
                <ColumnListItem>
                  <cells>
                    <template:repeat list="{lineItem>}" var="field">
                      <template:with path="field>Value/$Path" var="target">
                        <template:if test="{= ${target>@@AnnotationHelper.getValueListType} === 'Standard' }">
                            <template:then>
                                <Input value="{path : 'field>Value/@@value'}" showValueHelp="true", valueHelpRequest=".onValueHelp"}" />
                            </template:then>
                            <template:elseif test="{= ${target>@@AnnotationHelper.getValueListType} === 'Fixed' }">
                                <ComboBox value="{path : 'field>Value/@@value'}" loadItems=".onLoadItems" showValueHelp="true" />
                            </template:elseif>
                            <template:elseif test="{target>@com.sap.vocabularies.Common.v1.Text}">
                                <!-- Note: TextFirst, TextLast, TextSeparate, TextOnly -->
                                <template:if test="{= ${target>@com.sap.vocabularies.Common.v1.Text@com.sap.vocabularies.UI.v1.TextArrangement/$EnumMember}
                                    === 'com.sap.vocabularies.UI.v1.TextArrangementType/TextLast' }">
                                    <!-- Text: "A descriptive text for values of the annotated property.
                                        Value MUST be a dynamic expression when used as metadata annotation." -->
                                    <Text text="{field>Value/@@value} {target>@com.sap.vocabularies.Common.v1.Text/@@value}" />
                                </template:if>
                            </template:elseif>
                            <template:else>
                                <Text text="{field>Value/@@format}" />
                            </template:else>
                        </template:if>
                      </template:with>
                    </template:repeat>
                  </cells>
                </ColumnListItem>
              </items>
            </Table>
          </template:with>
        </template:with>
    </template:alias>
    </template:alias>
</mvc:View>

AnnotationHelper

The module sap/ui/model/odata/v4/AnnotationHelper delivers the following computed annotations; require it as shown in the example above:

Alternatively it can be called on an annotation holding an edm:Path to a property when it is called in the context of an entity type. This is typically the case when iterating over a com.sap.vocabularies.UI.v1.LineItem annotation of an entity type and asking for value help on the data fields. See the example regarding LineItem of BusinessPartnerList (the relevant parts are repeated here):


<template:with path="meta>/BusinessPartnerList/" var="entityType">
  <template:with path="entityType>@com.sap.vocabularies.UI.v1.LineItem" var="lineItem">
...    
            <template:repeat list="{lineItem>}" var="field">
              <template:with path="field>Value/$Path" var="target">
                <template:if test="{= ${target>@@AnnotationHelper.getValueListType} === 'Standard' }">
...

The first <template:with> defines entityType to be the type of the set BusinessPartnerList. The <template:repeat> iterates over its annotationcom.sap.vocabularies.UI.v1.LineItem (a collection of records with type com.sap.vocabularies.UI.v1.DataField). The record’s property Value is assumed to be an edm:Path pointing to a property of the entity type. For this path the value list type is determined.

Related Information

OData V4 Metadata JSON Format

getMetaModel

sap.ui.model.odata.v4.ODataMetaModel

requestObject

sap.ui.model.odata.v4.ODataMetaModel#getObject

sap.ui.model.odata.v4.ODataMetaModel#bindList