Я совершенно новый в SAPUI5 и JS. Есть кое-что, что я плохо понимаю относительно определения и использования модуля. Вот мой контекст:
Я хочу создать компонент my.test.comp
который использует внешний объект модуля my.test.comp.Service
. Поэтому, следуя рекомендациям, у меня есть следующий код:
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;
});
И теперь он работает хорошо. Я не понимаю, в чем отличия.
Может ли кто-нибудь объяснить мне, почему?
В 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() {
var service1 = new Service(); /* returns an object with ..
* __proto__: {
* getServiceRootPath: f ()
* }
*/
var serviceRootPath = service1.getServiceRootPath();
// ...
}
});
(Вы также можете напрямую получить доступ к методу с помощью Service.prototype.getServiceRootPath
без 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() {
var serviceRootPath = Service.getServiceRootPath();
// ...
}
});
});
Это тоже будет работать.
В вашем компоненте.js вам необходимо импортировать
"Мой/тест/сост/Сервис"
вместо
"./Обслуживание"