无法从具有 View byId 的控制器访问在 JSView 中创建的控件

Unable to access control, created in JSView, from controller with View byId

我正在尝试显示 VizFrame,我的数据采用简单的 JSON 格式。 我的视图和控制器都在 JS 中。 (我将在 XML 中开始写下我的观点)因为我认为这是要走的路。

我得到一个包含错误的空白页面:"setDataset of undefined"。我错过了什么?

我的查看代码是这样的

createContent: function(oController) {
  var oSubHeader = new sap.m.Bar({
    contentLeft: [
      new sap.m.Button({
        icon: "sap-icon://nav-back",
        press: [oController.onNavBack, oController]
      })
    ],
    contentMiddle: [
      new sap.m.Label({
        text: "{i18n>app_subhead_2}"
      })
    ]
  });
  var oVizFrame = new sap.viz.ui5.controls.VizFrame("VizFrameId", {
    width: "100%",
    height: "400px",
    vizType: "line"
  });
  var oPage = new sap.m.Page({
    title: "UI5 Assignment App",
    showSubHeader: true,
    subHeader: oSubHeader,
    content: [oVizFrame]
  });
  return oPage;
}

我对应的控制器是

sap.ui.define([
  "sap/ui/core/mvc/Controller",
  "sap/ui/core/UIComponent",
  "sap/ui/core/routing/History",
  "sap/viz/ui5/controls/VizFrame",
  "sap/viz/ui5/data/FlattenedDataset"
], function (Controller, UIComponent, History, VizFrame, FlattenedDataset) {
  "use strict";

  return Controller.extend("Project_Tile_learning.Divya_tile_Project.controller.ProductDetailPage", {
    onNavBack: function () {
      var oHistory = History.getInstance();
      var sPreviousHash = oHistory.getPreviousHash();
      if (sPreviousHash !== undefined) {
        window.history.go(-1);
      } else {
        var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
        oRouter.navTo("homepage", true);
      }
    },
    onInit: function () {
      var sampleDatajson = new sap.ui.model.json.JSONModel("json/PA.json");
      var oVizFrame = this.getView().byId("VizFrameId");
      var oDataset = new sap.viz.ui5.data.FlattenedDataset({
        dimensions: [{
          name: "Year",
          value: "{Year}"
        }],
        measures: [{
          name: "Supplier",
          value: "{Supplier}"
        }, {
          name: "Liquor",
          value: "{Liquor}"
        }, {
          name: "Quantity",
          value: "{Quantity}"
        }],
        data: {
          path: "/items"
        }
      });
      oVizFrame.setDataset(oDataset);
      oVizFrame.setModel(sampleDatajson);
      var oFeedValueAxis = new sap.viz.ui5.controls.common.feeds.FeedItem({
        "uid": "valueAxis",
        "type": "Measure",
        "values": ["Supplier"]
      });
      var oFeedValueAxis1 = new sap.viz.ui5.controls.common.feeds.FeedItem({
        "uid": "valueAxis",
        "type": "Measure",
        "values": ["Liquor"]
      });
      var oFeedValueAxis2 = new sap.viz.ui5.controls.common.feeds.FeedItem({
        "uid": "valueAxis",
        "type": "Measure",
        "values": ["Quantity"]
      });
      var oFeedCategoryAxis = new sap.viz.ui5.controls.common.feeds.FeedItem({
        "uid": "categoryAxis",
        "type": "Dimension",
        "values": ["Year"]
      });
      oVizFrame.addFeed(oFeedValueAxis);
      oVizFrame.addFeed(oFeedValueAxis1);
      oVizFrame.addFeed(oFeedValueAxis2);
      oVizFrame.addFeed(oFeedCategoryAxis);
    }
  });
});

更新:自 UI5 v1.90 起,JS 视图已弃用。请改用 Typed View


在 JS 视图定义中创建控件时,始终使用 <em>this.createId(</em>"myControl"<em>)</em>.

From the doc:

If you want to define IDs for controls inside a JSView to guarantee their uniqueness [...], you cannot give hardcoded IDs, but have to give the view the opportunity to add its own instance ID as a prefix. This is done by using the View.createId(...) method.

对于上面的例子,这样做是这样的:

新 sap.viz.ui5.controls.VizFrame(<strong><em>this.createId(</em></strong>"VizFrameId"<strong><em>)</em></strong>, { /*...*/ });

然后在controller中,myView.<strong><em>by</em></strong>Id尝试访问以view自己的ID为前缀的控件,这次成功了,因为controller有一个以view ID为前缀的ID。