Search code examples
sapui5

How to Load Dependencies Relative to Defining Module


I made a library project so I can share a formatter and some custom controls between applications. This works pretty well, it's just adding the library to the neo-app.json file. Now I can load my common formatter:

app/neo-app.json

{
    "path": "/resources/shared/",
    "target": {
        "type": "application",
        "name": "mysharedlibrary",
        "entryPath": "/"
    },
    "description": "My shared library"
}

app/Controller

sap.ui.define([
    "shared/formatters"
], function(formatters) {
//etc

Then I wanted to add a shared base controller, which already has the formatters set. So I go into my shared library project and add a controller, then add the formatter:

mysharedlibrary/SharedController

sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "formatters" /* <----- this is the problem */
], function(Controller, formatter) {
    "use strict";

    return Controller.extend("shared.SharedController", {
        formatter: formatter
    });
});

And then use it in my app:

app/Controller.js

// fails. Shared base controller can't load formatter. 
sap.ui.define([
    "shared/SharedController"
], function(Controller) {
    "use strict";

    return Controller.extend("my.app.controller.App", {

    });
});

This approach doesn't work. The app implementing this controller can find the controller, but then loading the formatter into the shared controller seems to fail because it can't be found. I'm not sure how to make the Shared Controller load files relative to it's own path instead of relative to the implementing application's path.

What do I put in the SharedController file to load the formatters?


Solution

  • sap.ui.define supports declaring dependencies relative to the module's own path.

    As a convenience, the name of a dependency can start with the segment './' which will be replaced by the name of the package that contains the currently defined module (relative name).

    It is best practice to [...] use relative names for the dependencies whenever possible.

    In the case above, if SharedController.js and formatters.js are stored in the same folder, the dependency of the controller would look like this:

    sap.ui.define([
      "sap/ui/core/mvc/Controller",
      "./formatters"
    ], function(Controller, formatter) {
      "use strict";
    
      return Controller.extend("shared.SharedController", {
        formatter: formatter
      });
    });
    

    If it's in upper directory, then like this: "../formatters", etc.