Lifecycle

The component class has methods that are called at a particular moment.

Component.prototype.constructor(element, scope)

  • element HTMLElement - html element controlled by the component
  • scope Proxy - object to synchronize with the component template (content)
class MyComponent extends Akili.Component {
  constructor(element, scope) {
    super(element, scope);

    console.log(element === this.el); // true;
    console.log(scope === this.scope); // true;
  }
}

First of all, during the compilation it will be created an instance of the component. Constructor takes element and scope. Here you can do anything with the element and its content. It is the place where you can prepare your component to compilation: change the element and set up default scope values, for example.

class MyComponent extends Akili.Component {
  constructor(element, scope) {
    super(element, scope);

    element.innerHTML = '${ this.example }';
    element.setAttribute('class', '${ this.className }');

    scope.example = 'Hello!';
    scope.className = 'example';
  }
}
Canceling the compilation

You can stop the component compilation if it is necessary. It is possible only in the constructor.

class MyComponent extends Akili.Component {
  constructor(...args) {
    super(...args);

    if(!this.el.hasAttribute('x')) {
      this.cancel();
    }
  }
}

So if the element does not have attribute x, the compilation will not happen. Further steps will be stopped. Another way to stop compiling without even getting into the constructor is the matches property using.

class MyComponent extends Akili.Component {
  static matches = '[x]';
}

Both examples above are equivalent

Prevent the compilation

Also you can prevent the compilation inside of the component.

class Code extends Akili.Component {
  constructor(...args) {
    super(...args);

    this.prevent();
  }
}
<code>${ example }</code>

After the compilation there will be the same code in the template, because the compilation was prevented.

<code>${ example }</code>

Component.prototype.created()

This is a logical extension of the constructor and will be called immediately after that if you didn't cancel the compilation in the constructor. At this stage, expressions in the component template is not parsed yet. You can't use .attr() and .store() methods here. It is good place to set default values, for example.

Component.prototype.compiled() Promise

At this stage all expressions are parsed. Component attributes, .attr() and .store() methods are available here.

Component.prototype.recompiled()

It is called on every recompilation of the component.

Component.prototype.resolved() Promise

This method is called after the full compilation of the component and all the nested components, even if they do some asynchronous operations. You have access to all the children components here.

class ParentComponent extends Akili.Component {
  resolved() {
    this.child('child-component').setTitle();
  }
}

class ChildComponent extends Akili.Component {
  constructor(...args) {
    super(...args);

    this.scope.title = '';
  }

  setTitle() {
    this.scope.title = 'Look at this!';
  }
}
<parent-component>
  <child-component>
    ${ this.title }
  </child-component>
</parent-component>

During the compilation all the stages of the component occur from top to bottom and from left to right in the hierarchy. But at this stage, the opposite is true: right to left and bottom to top.

Component.prototype.removed()

This method is called before the component removing.