Skip to content

Addressing: Adressing Stages

What are we learning here?

  • Components can be loaded with load(ComponentType,Id) which will set an id for addressing
  • Parent components can access these stages with this.getStage()

The stages created by our canvas component can be accessed by parent components (in our case it is our application component).

Let's extend our application and add a console output:

src/demo/apps/stages-flexbox/index.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import { Application } from "@codecoupler/cc-ui";
import Content from "./content.js";
export default class extends Application {
  static defaults = {
    "@codecoupler": {
      panel: {
        panelSize: "580 580",
        headerTitle: "Test Stage Features"
      }
    }
  };
  async start() {
    await this.stage.load(Content);
    console.info(this.getStages());
  }
}

You will see an output like this:

Object { main {}, ... }
► main: Object {  }
► "main/a38ABDd_814fYSpmyNyYc/luigi": Object {  }
► "main/a38ABDd_814fYSpmyNyYc/mario": Object {  }
► "main/a38ABDd_814fYSpmyNyYc/peach": Object {  }
► "main/a38ABDd_814fYSpmyNyYc/daisy": Object {  }

These are the paths to every stage that is accessible from the application. As you see the path starts always with the "main" stage of the application itself.

But what is the cryptic part "a38ABDd_814fYSpmyNyYc" in the path? This is the id of the widget that keeps the stages. This id is a random string and not very usefull. So let's assign an id to the widget. You can assign an id to any component with the load signature load(ComponentType, Id):

src/demo/apps/stages-flexbox/index.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import { Application } from "@codecoupler/cc-ui";
import Content from "./content.js";
export default class extends Application {
  static defaults = {
    "@codecoupler": {
      panel: {
        panelSize: "580 580",
        headerTitle: "Test Stage Features"
      }
    }
  };
  async start() {
    let main = await this.stage.load(Canvas, "flexbox-canvas");
    console.info(this.getStages());
  }
}

Start Definition Object vs Shortcut Signature

We will use here a signature of the load method which expects a Component and an id. This is just a shortcut signature. The load method normally expects a so called start definition object. This would look like:

load({
  component: Canvas,
  id: "flexbox-canvas"
})

Now you see in the console:

Object { main {}, ... }
► main: Object {  }
► "main/flexbox-canvas/luigi": Object {  }
► "main/flexbox-canvas/mario": Object {  }
► "main/flexbox-canvas/peach": Object {  }
► "main/flexbox-canvas/daisy": Object {  }

The path has the structure:

<Id of the own stage> / <Component id with public stages> / <Public stage id> [ ... ]

Let's now load components into this stages from our parent application component. For this we will use getStage() to get a specific stage and then we apply the method load() to the returned stage object.

We will create a very simple child component:

src/demo/apps/stages-flexbox/child.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import { Widget } from "@codecoupler/cc-ui";
export default class extends Widget {
  async start() {
    this.element.classList.add("p-2");
    this.element.innerHTML =
      `<p>Lorem ipsum dolor sit amet, consetetur sadipscing ` +
      `elitr, sed diam nonumy eirmod tempor invidunt ut labore ` +
      `et dolore magna aliquyam erat, sed diam voluptua. At vero ` +
      `eos et accusam et justo duo dolores et ea rebum. Stet clita ` +
      `kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor ` +
      `sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing ` +
      `elitr, sed diam nonumy eirmod tempor invidunt ut labore et ` +
      `dolore magna aliquyam erat, sed diam voluptua. At vero eos et ` +
      `accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, ` +
      `no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>`;
  }
}

We will start loading this child component into the stage named mario:

src/demo/apps/stages-flexbox/index.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import { Application } from "@codecoupler/cc-ui";
import Content from "./content.js";
import Child from "./child.js";
export default class extends Application {
  static defaults = {
    "@codecoupler": {
      panel: {
        panelSize: "580 580",
        headerTitle: "Test Stage Features"
      }
    }
  };
  async start() {
    await this.stage.load(Content, "flexbox-canvas");
    await this.getStage("mario").load(Child);
    console.info(this.getStages());
  }
}

Before we continue, let's clarify the following: We used now the stage name mario instead the full qualified path main/flexbox-canvas/mario. This is possible because there is no other stage with a name mario and therefore the name will be replaced with a glob pattern **/mario. And this leads to only one stage.

This makes it clear that we can also use glob patterns. Let's try the glob patterns **/luigi, main/*/peach and main/flexbox-canvas/daisy to address the other stages and load the same child component.

As we do not need to load the components sequentially, we will put all load statements into one promise. Furthermore we will set different ids for all child components:

src/demo/apps/stages-flexbox/index.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { Application } from "@codecoupler/cc-ui";
import Content from "./content.js";
import Child from "./child.js";
export default class extends Application {
  static defaults = {
    "@codecoupler": {
      panel: {
        panelSize: "580 580",
        headerTitle: "Test Stage Features"
      }
    }
  };
  async start() {
    await this.stage.load(Content, "flexbox-canvas");
    await Promise.all([
      this.getStage("mario").load(Child, "child-of-mario"),
      this.getStage("**/luigi").load(Child, "child-of-luigi"),
      this.getStage("main/*/peach").load(Child, "child-of-peach"),
      this.getStage("main/flexbox-canvas/daisy").load(Child, "child-of-daisy")
    ]);
    console.info(this.getStages());
  }
}

Now we expand our child component and will also create a public stage there:

src/demo/apps/stages-flexbox/child.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import { Widget } from "@codecoupler/cc-ui";
export default class extends Widget {
  async start() {
    this.element.classList.add("p-2");
    this.element.innerHTML =
      `<p>Lorem ipsum dolor sit amet, consetetur sadipscing ` +
      `elitr, sed diam nonumy eirmod tempor invidunt ut labore ` +
      `et dolore magna aliquyam erat, sed diam voluptua. At vero ` +
      `eos et accusam et justo duo dolores et ea rebum. Stet clita ` +
      `kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor ` +
      `sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing ` +
      `elitr, sed diam nonumy eirmod tempor invidunt ut labore et ` +
      `dolore magna aliquyam erat, sed diam voluptua. At vero eos et ` +
      `accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, ` +
      `no sea takimata sanctus est Lorem ipsum dolor sit amet.</p>`;
    let stageDiv = document.createElement("div");
    stageDiv.classList.add("m-2", "p-1", "border", "border-success");
    this.element.prepend(stageDiv);
    this.registerStage(stageDiv, "child-stage", "public");
  }
}

Let's have a look again into the console:

Object { main {}, ... }
► main: Object {  }
► "main/flexbox-canvas/daisy": Object {  }
► "main/flexbox-canvas/daisy/child-of-daisy/child-stage": Object {  }
► "main/flexbox-canvas/luigi": Object {  }
► "main/flexbox-canvas/luigi/child-of-luigi/child-stage": Object {  }
► "main/flexbox-canvas/mario": Object {  }
► "main/flexbox-canvas/mario/child-of-mario/child-stage": Object {  }
► "main/flexbox-canvas/peach": Object {  }
► "main/flexbox-canvas/peach/child-of-peach/child-stage": Object {  }

You will see now new stages inside of our child components. You see you can address even stages in deeper levels and nested components if they are public.

Let's load a component named Message, which display (no wonder) just a message, into all child stages.

src/demo/apps/stages-flexbox/index.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { Application, Message } from "@codecoupler/cc-ui";
import Content from "./content.js";
import Child from "./child.js";
export default class extends Application {
  static defaults = {
    "@codecoupler": {
      panel: {
        panelSize: "580 580",
        headerTitle: "Test Stage Features"
      }
    }
  };
  async start() {
    await this.stage.load(Content, "flexbox-canvas");
    await Promise.all([
      this.getStage("mario").load(Child, "child-of-mario"),
      this.getStage("**/luigi").load(Child, "child-of-luigi"),
      this.getStage("main/*/peach").load(Child, "child-of-peach"),
      this.getStage("main/flexbox-canvas/daisy").load(Child, "child-of-daisy")
    ]);
    await Promise.all([
      this.getStage("**/child-of-mario/child-stage").load(Message),
      this.getStage("**/child-of-luigi/child-stage").load(Message),
      this.getStage("**/child-of-peach/child-stage").load(Message),
      this.getStage("**/child-of-daisy/child-stage").load(Message)
    ]);
    console.info(this.getStages());
  }
}