# Alpine structure of LokiComponents

**LokiComponents can be seen as a composition of various files - PHP classes, PHTML templates, XML snippets ... and an AlpineJS component. Because the AlpineJS component - by definition - inherits from a parent object `LokiComponentType`, there are various pieces of functionality that automatically can be used.**

## AJAX calls and targets
The very essence of LokiComponents is that they allow you to make an AJAX call to the Magento backend to change some state (for instance, add an attribute value to the current quote or set some flag in the customer session): The **component update**. This is done via the `post()` method in `LokiComponentType`.

Built into this `post()` method is a mechanism of `targets`. The AlpineJS component receives an array of `targets` (which resembles a listing of DOM IDs which then again correspond with layout-based block names), so that - once the component update is done - the layout-based blocks are rendered and their HTML is sent back within the same AJAX call. Next, the relevant DOM areas are updated.

## Loading state
Various additional tricks come in play here: For instance, there is an Alpine component property `loading` that is automatically toggled via the `post()` method. This could lead to a loader icon or a loader overlay to be displayed while `loading` is `true`. However, the `loading` is only shown if the AJAX call takes longer than `showLoaderTimeout`: Because of this, the flag `showLoader` is used in the HTML instead.

In a similar way, the HTML attribute `aria-busy` is applied to the DOM element as well.

## Abort controllers
When subsequent AJAX request is sent, while an existing AJAX request is still pending, the previous request is canceled via the browser `abortController` technology.

## initMethods and destroyMethods
In an Alpine component, you could use the `init()` method when initializing things and you could undo things again with `destroy()`. An example for this is an initial AJAX call that is required once the Alpine component is loaded. Or a Web Component that needs to be unmounted again when destroying the Alpine component.

However, because Loki Components are made very extensible (as a Loki Component is composed out of parent objects, component partials and custom implementations), it is not uncommon to add your own initialization on top of the core logic. However, the recommendation is **not** to touch upon the `init()` and `destroy()` method at all.

Instead, the parent behaviour of Loki Components guarantees that any method that starts with the word `init` is run via `init()`. And likewise, any method that starts with the word `destroy` is run via `destroy()`.

The following example component illustrates this: The `initExample()` method and the `destroyExample()` are automatically called.

```js
document.addEventListener('alpine:init', () => {
    Alpine.data('Example', () => ({
        ...LokiComponentType,
        initExample() {
            ...
        },
        destroyExample() {
            ...
        }
    }));
});
```
