首页 > 解决方案 > 单独模块中的模块定义和使用

问题描述

我对 SAPUI5 和 JS 很陌生。关于模块定义和使用,我不太了解。这是我的背景:

我想创建一个my.test.comp使用外部模块对象的组件my.test.comp.Service。因此,遵循最佳实践,我有以下代码:

服务.js:

sap.ui.define([
  "sap/ui/base/Object"
], function(BaseObject) {
  "use strict";

  var modulePath = jQuery.sap.getModulePath("my.test.comp");
  var SERVICE_ROOT_PATH = modulePath.lastIndexOf("/") > 0
     ? modulePath.substring(0, modulePath.lastIndexOf("/"))
     : "/test";
  var Service = BaseObject.extend("my.test.comp.Service", {
    getServiceRootPath: function () {
      return SERVICE_ROOT_PATH;
    }
  });

  return Service;
});

我在Component.js 中使用它:

sap.ui.define([
  "sap/ui/core/Component",
  "./Service"
], function(Component, Service) {
  "use strict";

  return Component.extend("my.test.comp.Component", {
    init: function() {
      var serviceRootPath = Service.getServiceRootPath();
      jQuery.sap.log.error("ServicePathInfo : " + serviceRootPath);
    }
  });
});

当我运行它时,我收到一个错误,说getServiceRootPath未定义,并引发错误。

所以我改变了Service.js如下:

sap.ui.define([
  "sap/ui/base/Object"
], function(BaseObject) {
  "use strict";

  var modulePath = jQuery.sap.getModulePath("my.test.comp");
  var SERVICE_ROOT_PATH = modulePath.lastIndexOf("/") > 0
    ? modulePath.substring(0, modulePath.lastIndexOf("/"))
    : "/test";
  var Service = BaseObject.extend("my.test.comp.Service");
  Service.getServiceRootPath = function () {
    return SERVICE_ROOT_PATH;
  };

  return Service;
});

现在它运行良好。我不明白有什么区别。

有人可以解释我为什么吗?

标签: javascriptsapui5

解决方案


在 JS 中,没有类。有{}可以用 . 调用的普通对象 ( ) 或带有构造函数的函数new

因此,.extend("...")在 UI5 中调用会再次返回一个函数,其构造函数与任何其他函数一样,可以与new. 您的模块成员(方法、属性等)将被添加到原型中,而不是添加到父函数 ( Service) 本身。

BaseObject.extend("my.test.comp.Service", {
  // methods in prototype ...
});

所需的Service模块(即函数)仅由一个构造函数(Service.constructor)和一个原型对象(Service.prototype)组成。这就是为什么Service.getServiceRootPath在您的第一种情况下未定义。您需要先调用构造函数new

return Component.extend("my.test.comp.Component", {
  init: function() {
    const service1 = new Service(); /* returns an object with ..
    *  __proto__: {
    *    getServiceRootPath: f ()
    *  }
    */
    const serviceRootPath = service1.getServiceRootPath();
    // ...
  },
});

(您也可以使用Service.prototype.getServiceRootPathwithout直接访问该方法new

这也解释了为什么Service.getServiceRootPath在第二种情况下有效。您可以将几乎任何您喜欢的东西添加到现有函数中,因为函数最终也是对象


看起来您的意图不是创建多个“服务”,而是创建一个包含方法的简单对象。在这种情况下,只需在模块定义中返回一个带有方法的简单对象。

sap.ui.define([
 // Without "sap/ui/base/Object"
], function() {
  "use strict";
  //...
  return {
    getServiceRootPath: function () {
      // ...
    },
  };
});
sap.ui.define([
  "sap/ui/core/Component",
  "./Service",
], function(Component, Service) {
  "use strict";

  return Component.extend("my.test.comp.Component", {
    init: function() {
      const serviceRootPath = Service.getServiceRootPath();
      // ...
    },
  });
});

这也将起作用。


推荐阅读