Skip to content

Stages: Sum-up Stages

What are we learning here?

  • Some last important details of stages

Special Stage "root"

There is another stage that each component has with the id root. This stage includes the entire component, regardless of the part in which the main stage was defined.

This makes sense if, for example, you want to block the entire component in conjunction with the block level as we will see later.

For components like widget or canvas components there is no difference between the root and the main stage. In an application component for example it can be different as we will see in the next chapters.

Public and Private Access

Stages that will be created in the start() method are by default private. This means that parent components cannot access them over the method getStage().

Maybe you have noticed that the main stage of a widget is not returned by the getStage() method of a parent application. This is because main stages are always private.

To make a stage public you have to use a third argument in this.registerStage(Element,Id,access). The argument access can be public or private.

Create Stage from Flexbox Childs

Using a flexbox child to create a stage can be confusing. CodeCoupler tries to make this easier by addding flex-basis: 0 if the element has flex-grow: 1. This is because otherwise the element could grow with the content of a widget component and this is not always the intention.

With this setting nested flexboxlayout like this will work:

<div class="h-100 d-flex flex-column">
    <div class="flex-grow-1 d-flex flex-column">
        <div class="p-2 border border-success">some</div>
        <!-- Create a stage here and load here a scrollable widget -->
        <!-- The element gets automatically "flex-basis:0" to get a stable container height -->
        <div class="p-2 flex-grow-1 border border-success"></div>
    </div>
</div>

On the other hand the stage element could collapse like here:

<div class="h-100 d-flex flex-column">
    <!-- Create a stage here and load here a scrollable widget -->
    <!-- The element gets automatically "flex-basis:0" and collapse -->
    <div class="flex-grow-1 d-flex flex-column"></div>
</div>

In this case you should create the stage in an additional element:

<div class="h-100 d-flex flex-column">
    <div class="flex-grow-1 d-flex flex-column">
        <!-- Create a stage here and load here a scrollable widget -->
        <div></div>
    </div>
</div>

The difference between the base level and all other levels

In a previous chapter we loaded the component loading-components.js into an empty stage which initially did not have a height. And as you have seen, the stage has automatically adapted to the content. However, this is not always the case.

We roughly sketch how a stage with loaded components looks like:

┌────────────────────────────────────────┐
│ Stage DOM Element                      │
│┌──────────────────────────────────────┐│
││ Stage Level DOM Element "foreground" │<- potition: absolute
││┌────────────────────────────────────┐││
│││ Component 1 in level "foreground"  │││
││└────────────────────────────────────┘││
││┌────────────────────────────────────┐││
│││ Component 2 in level "foreground"  │││
││└────────────────────────────────────┘││
│└──────────────────────────────────────┘│
│┌──────────────────────────────────────┐│
││ Stage Level DOM Element "base"       │<- potition: relative
││┌───────────────────────────────────┐ ││
│││ Component 1 in level "base"       │ ││
││└───────────────────────────────────┘ ││
││┌───────────────────────────────────┐ ││
│││ Component 2 in level "base"       │ ││
││└───────────────────────────────────┘ ││
│└──────────────────────────────────────┘│
│┌──────────────────────────────────────┐│
││ Stage Level DOM Element "background" │<- potition: absolute
││┌────────────────────────────────────┐││
│││ Component 1 in level "background"  │││
││└────────────────────────────────────┘││
││┌────────────────────────────────────┐││
│││ Component 2 in level "background"  │││
││└────────────────────────────────────┘││
│└──────────────────────────────────────┘│
└────────────────────────────────────────┘

As you see the components in the levels foreground and background are encapsulated into own DOM nodes which are positioned absolute.

So if would load a component into an empty stage into the level foreground the stage would not adapt its height to the height of the component.

Elements that Sharing Stages

Stages are not just an element. They are more like contexts in which components live.

For example in a widget component the stage root and the stage main share the same element. But in each of these stages you can load a component with the same id. This is because the components are owned by a stage, not by the element of the stage. And every stage manage its own set of component id's.

On the other hand the levels of the stage and its stacking context will be shared by all stages. So it doesn't matter if two stages add components into the same level. The fronting, hiding and stacking within the level will be handled correctly.

Load into a Level Alternatives

As you have seen the load method can get an argument "level" which define the level in which the component should be loaded. This is just a simplification. The level in which a component will be loaded is defined in its default value $manifest.level which can be overriden of course. So both of the following codes do the same:

1
2
3
4
5
6
this.stage.load({
    component: MyComponent,
    level: "background"
})
// Or as shortcut signature:
// this.stage.load("background", MyComponent)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
this.stage.load({
    component: MyComponent,
    options: {
        $manifest: {
            level: "background"
        }
    }
})
// Or as shortcut signature:
// this.stage.load(MyComponent, {
//     $manifest: {
//         level: "background"
//     }
// })