Skip to content

Options: Changing Options

A component has a public available setter named options with which you can set new options. The setter expects an object with new values that are merged with the existing values. The component can listen to this changes with this.on("changed.options"). The detailed event handling will be explained later.

What are we learning here?

  • Options can be changed via the setter component.options
  • Options changes will trigger the event changed.options

Let's add code to listen to changes:

src/demo/apps/widget-basics/content.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
import { Widget } from "@codecoupler/cc-ui";
import template from "./content.ejs.html";
import LoadingComponents from "../../widgets/loading-components";
export default class extends Widget {
  myHeader = "JS Widget Basics";
  static defaults = {
    myWidgetArg1: "Default 1",
    myWidgetArg2: "Default 2"
  };
  async start() {
    this.injectTemplate(template({
      myHeader: this.myHeader,
      Argument1: this.options.myWidgetArg1,
      Argument2: this.options.myWidgetArg2
    }));
    await this.registerStage(this.element.find("[data-role=stage]")).load(
      LoadingComponents
    );
    this.on("changed.options", () => {
      this.element.find("[data-role=arg1]").text(this.options.myWidgetArg1);
    });
  }
  injectTemplate(tpl) {
    this.element.html(tpl);
  }
}

React

The event method will receive the new passed options as argument. Sometimes the merged options are not that what you need. So the following code will react only if myWidgetArg1 was changed, however, the result remains the same as the code above:

1
2
3
4
this.on("changed.options", (changes) => {
  if(changes.new.myWidgetArg1)
    this.element.find("[data-role=arg1]").text(changes.new.myWidgetArg1);
});

Keep in mind, that new array values will be merged with the prvious array. If this is not intended you can override the behaviour with:

1
2
3
this.on("changed.options", (changes) => {
  if(changes.new.myArrayValue) this.options.myArrayValue = changes.new.myArrayValue
});

Now we add code to change the value of this.options.myWidgetArg1 in our application, where we have instatiated the widget. We use a new method called boot() which will be called after the initialization phase:

src/demo/apps/widget-basics/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 } from "@codecoupler/cc-ui";
import ChildComponent from "./content.js";
export default class extends Application {
  static defaults = {
    "@codecoupler": {
      panel: {
        panelSize: "640 400",
        headerTitle: "Test Widget Features"
      }
    }
  };
  async start() {
    this.widget = await this.stage.load(ChildComponent, {
      myWidgetArg1: "Value 1"
    });
  }
  async boot() {
    for (;;) {
      if (!this.widget.isDestroyed) {
        await new Promise((r) => setTimeout(() => r(), 2000));
        this.widget.options = {
          myWidgetArg1: `Value ${Math.floor(Math.random() * 100)}`
        };
      } else {
        break;
      }
    }
  }
}

Now the value will change every 2 seconds.