Skip to content

Loading Components: Applications

Now that we know everything about stages, levels and the load method we want to switch back to our basic-widgets application. As you know now every component can load further components in its always present main or root stage. So we will now explore some useful cases in which our widget loads more components.

One usefull case for loading a component into a widgets stage is to load application components. These applications can be dragged only inside of the area of the widget. They can be used for example as toolbox-windows or permanent displaying informations.

Applications will be loaded by default into the level foreground. So they don't collide with our widget content.

What are we learning here?

  • Application components will be loaded by default into the level foreground
  • A component instance can be accessed with $this

First this we switch back to our first widget-basics application:

src/system.js

1
2
3
4
5
6
7
import { Component } from "@codecoupler/cc-ui";
import TestApp from "./demo/apps/widget-basics";
export default class extends Component {
  async boot() {
    await this.stage.load(TestApp);
  }
}

Now we add two buttons into the HTML structure of the component that we have loaded into our first stage (replace the placeholder paragraph):

src/demo/widgets/loading-components/index.html

1
2
3
4
5
6
7
8
9
<div class="border rounded d-inline-block p-1 mr-2 mt-2">
  App
  <button class="btn btn-xs btn-info" data-role="inline-app-noid">
    <i class="fas fa-times-circle"></i>
  </button>
  <button class="btn btn-xs btn-info" data-role="inline-app-id">
    <i class="fas fa-check-circle"></i>
  </button>
</div>

And attach some handlers:

src/demo/widgets/loading-components/index.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import { Box, MockApplication } from "@codecoupler/cc-ui";
import template from "./index.html";
export default class extends Box {
  async finalize() {
    super.finalize();
    this.$box.html(template);
    let $this = this.options.target || this.env.parent;
    this.$box.find("[data-role=inline-app-noid]").on("click", async () => {
      await $this.stage.load(MockApplication);
    });
    this.$box.find("[data-role=inline-app-id]").on("click", async () => {
      await $this.stage.load(MockApplication, "some-id");
    });
  }
}

We load an application component with the method load(). Please note that we are using an inner component that is loaded in a stage of an outer widget. As we want to load the application in our outer widget we have to use this.env.parent.load() instead of just this.load(). With this.env.parent you can access the component from which we are loaded.

For the sake of simplicity, we've wrapped this.env.parent over $this and use that variable instead of this. We also have prepared this to be determined it by the option target. We will use it later.

We're using a built-in application MockApplication here that doesn't do much except display the id of the application.

You will see new buttons:

  • ×: Start an application without an id
  • : Start an application with an id

As you can see you can load with × an application without an id with the load method signature this.load(ComponentType). In this case every application (or any other component) will get a random id. use the signature this.load(ComponentType, Id) and load the application with an specific id. As we already know loading components with an already existing id will front them and not load them a second time.