Templates / Named templates

Sometimes may want to have slightly different templates used to create new component instances, but they would still be templates for the same component. Suppose you want comments from site admin to have a yellow background, so you just add another template:

Notice the data-template-name attribute on line 16 - that's how we name our template so the Component.create() constructor can later identify it.

For all of this to work, we'd need to make a few changes in our components Javascript code. First to our AddCommentButtonComponent:

export class AddCommentButtonComponent extends extend_as("AddCommentButtonComponent").mix(Component).with() {

  constructor() {
    super();
    this.native_events = ["click"];
    this.attribute_names = ["comment_type"];
    this.event_handlers.add({
      event: "click",
      role: "#self",
      handler: (self,event) => {
        CommentComponent.create({
          template_name: self.get("comment_type"),
          container: self.comment_container,
          attrs: { text: "new comment" }
        });
      }
    });
  }

  afterInitialize() {
    this.updateAttrsFromNodes();
    this.comment_container = RootComponent.instance.findFirstChildByRole("comment_container");
  }

}

On line 6 here we add a new attribute called type (and we previously set its value to admin) in html for the button responsible for creating admin comments). Next, on line 12, we pass this value in the component_template argument, so that the .create() constructor knows which template to use. And on line 21 (which is inside afterInitialixe() callback, which is run before the button is clicked) we load the comment_type attribute value from html we've just written above.

The last change we need to make is to make our CommentComponent constructor accept option, because that's how the template name is being passed to the newly created instance:

export class CommentComponent extends extend_as("CommentComponent").mix(Component).with() {
  constructor(options={}) {
    super(options);
    this.attribute_names = ["text"];
  }
}

Strictly speaking, it's better to always have that options={} argument declared in your component's constructor and then pass it to the parent class constructor with super(options), but it can be ommited because javascript doesn't enforce number of arguments in a function

After making these changes, we can click the "Add admin comment" button and we'll get the following html in our browser: