0

我使用“SAP Fiori Master-Detail Application”模板创建了一个 SAPUI5 应用程序。我的 Master 和 Detail 页面正常工作并正确连接到我的 OData 服务。我现在要做的是将详细信息页面路由到第二个(不同的)详细信息页面。

第一个 Detail 页面(我将称为 Detail1)包含 Detail2 对象的列表。单击列表中的这些对象之一应该会将您带到 Detail2 页面(它会显示更多信息)。

我使用 WebIDE 创建了一个新的 Detail2 视图和控制器,因此它带有一些填充代码。我还在 manifest.json 文件中创建了一个新路由:

{
    "name": "detail2Object",
    "pattern": "Detail2(Master={masterId},Id={detail1Id})",
    "titleTarget": "",
    "greedy": false,
    "target": ["master", "detail2"]
}

"detail2Object": {
    "viewType": "XML",
    "transition": "slide",
    "clearAggregation": true,
    "viewName": "Detail2",
    "title": "",
    "viewId": "detail2page",
    "viewLevel": 3
}

从模式中可以看出,该服务接受两个参数:Master 和 ID(即 Master ID 和第一个 Defects Id)。

独立于我的应用程序测试服务返回数据就好了: http://{root}.com:{port}/sap/opu/odata/sap/TEST_SRV/Detail2(‌​Master='552364',Id='‌​0004')

我在 Detail1 控制器中创建了一个 NavTo 函数来传递 Master 和 Id 参数:

_onNav : function (oEvent) {
            // get the list item, either from the listItem parameter or from the event's source itself (will depend on the device-dependent mode).
            this._showDetail2(oEvent.getParameter("listItem") || oEvent.getSource());
},

_showDetail2 : function (oItem) {
            this.getRouter().navTo("detail2Object", {
                masterId: oItem.getBindingContext().getProperty("Master"),
                detail1Id: oItem.getBindingContext().getProperty("Id")
            });
}

当我通过 WebIDE 测试(使用实时 OData 和我创建的 Mockdata)运行应用程序时,单击 Detail1 页面中的 Detail2 对象会将我导航到显示此错误的新页面:

此 <"ObjectName"> 不可用

进入 F12 工具,我看到以下错误:

MockServer:键“Id”中格式错误的 URI 文字语法 -

HTTP 请求失败400,Bad Request,{"error":{"code":400,"message":{"lang":"en","value":"键 'Id' 中的 URI 文字语法格式错误"}}} -

即使 url 正确提取了参数,也会发生这种情况:

http://localhost:54634/webapp/test/mockServer.html?hc_reset&origional-url=mockServer.html&sap-ui-appCacheBuster=..%2F..%2F..%2F&sap-ui-xx-componentPreload=off#/ Detail2(Master= '552364',Id='0004')

通过大量研究,我唯一发现的是这个错误可能与元数据文件有关。但是,两个 ID 都是类型Edm.String,并且它们的拼写方式完全相同,所以我认为这不是问题所在。此外,如前所述,服务运行良好,使用独立于应用程序运行的相同参数。

任何帮助将不胜感激。

更新

Detail1 视图,其中包含 Detail2 对象的列表:

        <List noDataText="Drop list items here" id="__list0" items="{DetailToDetail2}" headerText="Defects">
            <items>
                <ObjectListItem type="Navigation" title="{Detail2Title}" number="{Qty}" numberUnit="Detail Qty" press="_onNav">
                <attributes>
                    <ObjectAttribute text="{Detail2_Attr}" id="__attribute11" title="Detail2 Attr"/>
                    <ObjectAttribute id="__attribute12" title="Detail2 Attr2" text="{Detail2_Attr2}"/>
                </attributes>
                </ObjectListItem>
            </items>
        </List>

在服务的item="{DetailToDetail2}"元数据中显示为 NavigationProperty 和 Association。

这是它在 Detail1 实体中的外观:

<NavigationProperty Name="DetailToDetail2" Relationship="TEST_SRV.DetailToDetail2" FromRole="FromRole_DetailToDetail2" ToRole="ToRole_DetailToDetail2"/>

这是整个 Detail2 实体:

        <EntityType Name="Detail2" sap:content-version="1">
            <Key>
                <PropertyRef Name="Id"/>
                <PropertyRef Name="Master"/>
            </Key>
            <Property Name="Id" Type="Edm.String" Nullable="false" MaxLength="4" sap:unicode="false" sap:label="Id" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
            <Property Name="Master" Type="Edm.String" Nullable="false" MaxLength="12" sap:unicode="false" sap:label="Master" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
            <Property Name="Attr1" Type="Edm.String" MaxLength="40" sap:unicode="false" sap:label="Attribute 1" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
            <Property Name="Qty" Type="Edm.Int32" sap:unicode="false" sap:label="Detail Qty" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
            <Property Name="Attr2" Type="Edm.String" MaxLength="40" sap:unicode="false" sap:label="Attribute 2" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
            <Property Name="Attr3" Type="Edm.String" MaxLength="4" sap:unicode="false" sap:label="Attribute 3" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
        </EntityType>

这是 DetailToDetail2 关联:

        <Association Name="DetailToDetail2" sap:content-version="1">
            <End Type="TEST_SRV.Detail1" Multiplicity="1" Role="FromRole_DetailToDetail2"/>
            <End Type="TEST_SRV.Detail2" Multiplicity="*" Role="ToRole_DetailToDetail2"/>
            <ReferentialConstraint>
                <Principal Role="FromRole_DetailToDetail2">
                    <PropertyRef Name="Id"/>
                </Principal>
                <Dependent Role="ToRole_DetailToDetail2">
                    <PropertyRef Name="Master"/>
                </Dependent>
            </ReferentialConstraint>
        </Association>
4

1 回答 1

0

我发现“格式错误的 URI”错误不是发生在路由或导航中,而是在到达页面后发生绑定。

我的 Detail2 控制器 _onObjectMatched 函数如下所示:

_onObjectMatched : function (oEvent) { 
        var sObjectMasterId =  oEvent.getParameter("arguments").masterId; 
        var sObjectDetailId =  oEvent.getParameter("arguments").detail1Id; 
        this.getModel().metadataLoaded().then( function() { 
          var sObjectPath = this.getModel().createKey("Detail2", { 
            masterId:  sObjectMasterId, 
            detail1Id : sObjectDetailId 
          }); 
          this._bindView("/" + sObjectPath); 
        }.bind(this)); 

通过调试我发现sObjectPath变量被设置为Detail2(Id=null, Master=null). 那是当我意识到masterId并且detail1Id不是正确的参数名称时,因为我们没有绑定到路由,我们正在绑定到路径。所以我masterIdMasterdetail1Id替换了Id

_onObjectMatched : function (oEvent) { 
    var sObjectMasterId =  oEvent.getParameter("arguments").masterId; 
    var sObjectDetailId =  oEvent.getParameter("arguments").detail1Id; 
    this.getModel().metadataLoaded().then( function() { 
      var sObjectPath = this.getModel().createKey("Detail2", { 
        Master:  sObjectMasterId, 
        Id: sObjectDetailId 
      }); 
      this._bindView("/" + sObjectPath); 
    }.bind(this)); 

瞧,它奏效了!

感谢所有回复并指出我远离路由并走向绑定的人。我建议任何收到“格式错误的 URI”错误的人检查所有绑定和导航,以验证所有参数是否拼写正确。

查看带有参数的路由教程也很有帮助。

于 2017-11-15T13:41:22.927 回答