Creating UI/KnockoutJS components

To this point, we have only been dealing with jQuery widgets as components. While extremely powerful, jQuery widgets are not best suited for rendering robust components with complex HTML structures. The other type of JS components is what we refer to as UI/KnockoutJS components. Built on the shoulders of the KnockoutJS library, these components allow powerful templating of our data, among other things. Without getting too deep into the ins and outs of these type of components, suffice to say that the main construct we are referring to when we speak of UI/KnockoutJS components is uiComponent.

As per <MAGENTO_DIR>/module-ui/view/base/requirejs-config.js, the uiComponent maps to the Magento_Ui/js/lib/core/collection JS file. Inspecting the collection.js file, we can see that uiComponent extends uiElement, which maps to the Magento_Ui/js/lib/core/element/element JS file. The uiComponent and uiElement make use of the ko, underscore, mageUtils, uiRegistry, uiEventsand uiClass libraries, among other things, so it's worth getting ourselves familiar with those.

Creating new UI/KnockoutJS components is a slightly more involved process than creating a jQuery widget.

We start by creating the proper mapping under our <MODULE_DIR>/view/frontend/requirejs-config.js file, as follows:

var config = {
map: {
'*': {
popularProducts: 'Magelicious_Jsco/js/popular-products'
}
}
};

This part is the same as with jQuery widgets. Here we simply register, or alias if you will, our component name to its file location. 

We then define the component itself, under the <MODULE_DIR>/view/frontend/web/js/popular-products.js file, as follows:

define([
'jquery',
'uiComponent',
'ko',
'mage/translate'
], function ($, Component, ko, $t) {
'use strict';
return Component.extend({
defaults: {
template: 'Magelicious_Jsco/popular-products',
title: $t('Popular Products'),
products: [],
},
getTitle: function () {
return this.title;
}
});
}
);

The basis of all UI components is uiComponent. We pass on the instance of uiComponent as a Component parameter. We then implement the specifics of our component as part of the  JSON object passed onto the Component.extend method.

With our component JS file now in place, we further create the template file referenced by the component. We do so under the <MODULE_DIR>/view/frontend/web/template/popular-products.html file, as follows:

<h4 data-bind="text: getTitle()"></h4>
<ul data-bind="foreach: products">
<li>
<span>
<span data-bind="text: title"></span>
(<span data-bind="text: sku"></span>)
</span>
</li>
</ul>

What happens in the HTML template files is all about KnockoutJS, which means a certain part of the KnockoutJS library is required in order to built UI/KnockoutJS components.

See http://knockoutjs.com for more information on the KnockoutJS library.

We then amend our jsco_playground_index.xml by adding the following line under <referenceContainer name="content">:

<block name="popular_products" 
template="Magelicious_Jsco::popular-products.phtml" />

popular-products.phtml is where we will instantiate our UI/KnockoutJS component.

Finally, we create <MODULE_DIR>/view/frontend/templates/popular-products.phtml with content, as follows:

<?php $jsonHelper = $this->helper('MagentoFrameworkJsonHelperData'), ?>

<div class="popular-products" data-bind="scope:'popular-products-scope'">
<!-- ko template: getTemplate() --><!-- /ko -->
</div>

<script type="text/x-magento-init">
{
".popular-products": {
"Magento_Ui/js/core/app": {
"components": {
"popular-products-scope": {
"component": "popularProducts",
"products": <?= /* @escapeNotVerified */ $jsonHelper->jsonEncode([
['sku' => 'sku1', 'title' => 'Title1'],
['sku' => 'sku2', 'title' => 'Title2']
]) ?>
}
}
}
}
}
</script>

Here we are using the declarative approach to initialize our component. The structure of the JSON object under the script tag might seem a bit confusing at first. The .popular-products key is essentially a selector, targeting whatever HTML element it might find. Magento_Ui/js/core/app is an alias for the  app.js file, which creates the UI components instances according to the configuration of the JSON using  theuiLayout component. components is a key under which we nest one or more components we wish to initialize. popular-products-scope is sort of a scope key assigned to our component, which we use to data-bind the scope value to the HTML element.

Clearing the cache and redeploying the static files, we should now be able to see our newly created component.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.100.120