ComponentRepository
The example given under the page A simple component is really a basic example to get you started. It lacks the ability to modify data on the Magento side. To allow you to do that, a repository needs to be added.
First, add the following to the XML file etc/loki_components.xml
:
<?xml version="1.0" encoding="UTF-8" ?>
<components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Yireo_LokiComponents:etc/loki_components.xsd">
<component
name="loki-components.example"
repository="YireoTraining\ExampleLokiComponent\Component\Example\ExampleRepository"
/>
</components>
Clean the configuration cache afterwards.
ComponentRepository
classA new PHP class YireoTraining\ExampleLokiComponent\Component\Example\ExampleRepository
now needs to be created in our module. This class is dubbed the ComponentRepository
class in a component, because it extends upon a class Yireo\LokiComponents\Component\ComponentRepository
. This parent class is abstract
and forces you to create two methods:
getValue()
which retrieves data from the storage of your choice and adds them to the ViewModel
;saveValue(mixed $value)
which saves data to the storage of your choice;Let's use the customer storage to store a random value and display this as well:
namespace YireoTraining\ExampleLokiComponent\Component\Example;
use Yireo\LokiComponents\Component\ComponentRepository;
class ExampleRepository extends ComponentRepository
{
public function getValue(): mixed
{
return $this->getContext()->getCustomerSession()->getExampleValue();
}
public function saveValue(mixed $value): void
{
$this->getContext()->getCustomerSession()->setExampleValue(rand());
}
}
Because the repository is now part of the component, the button click of the previous example will send an AJAX call to the Magento application, which will then trigger the ExampleRepository::saveValue()
value (saving a random number to the customer session).
Next, the same AJAX call renders the block loki-components.example
(with a $viewModel
variable being an instance of the generic Yireo\LokiComponents\Component\ComponentViewModel
class) and refreshes the HTML of that block in the browser (so the HTML element with ID loki-components-example
).
If we modify the PHTML template to the following, the random value is fetched from the $viewModel
and shown:
<div>
<span>Random value: <?= $viewModel->getValue() ?></span><br/>
<button @change="post">Refresh</button>
</div>
We can also extend the component with a simple custom value. This is already built in within every Loki Component. Note however that there is no preference for the type of the value (string, boolean, array, integer). Casting will need to be done manually.
First of all, let's add an input field with the Alpine directive x-model
pointing to the component property value
:
<div>
<span>My value: <?= $viewModel->getValue() ?></span><br/>
<input type="text" x-model="value" /><br/>
<button @change="post">Refresh</button>
</div>
Now, modifying value in the input
field, will make sure that the same ExampleRepository
class stores the $value
. Even though it is not required, it is nice to modify the repository slightly to cast any value to a string:
class ExampleRepository extends ComponentRepository
{
public function getValue(): mixed
{
return (string)$this->getContext()->getCustomerSession()->getExampleValue();
}
public function saveValue(mixed $value): void
{
$this->getContext()->getCustomerSession()->setExampleValue((string)$value);
}
}
We can automatically apply a filter to the input value, simply by modifying the component definition. For instance, we can transform any input value into an uppercase string, by applying the uppercase
filter:
<?xml version="1.0" encoding="UTF-8" ?>
<components xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Yireo_LokiComponents:etc/loki_components.xsd">
<component
name="loki-components.example"
repository="YireoTraining\ExampleLokiComponent\Component\Example\ExampleRepository">
<filter name="uppercase" />
</component>
</components>
Coming soon