Categories


Archives


Recent Posts


Categories


Magento 2: The uiElement Provider and Source Defaults

astorm

Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

No Frills Magento Layout is the only Magento front end book you'll ever need. Get your copy today!

The next two defaults we’ll blitz through are the provider and source defaults.

#File: vendor/magento/module-ui/view/base/web/js/lib/core/element/element.js
defaults:{
    /* ... */
    provider: '',
    /* ... */        
    source: null,
    /* ... */        
}

We’re starting to get into the defaults that are tricky to understand since they involve both a server side component, and are effected by things that happen in the Magento_Ui/js/core/app and Magento_Ui/js/core/renderer/layout modules.

First, lets focus strictly on the javascript side. When you instantiate a uiElement based object, Magento calls the following method

#File: vendor/magento/module-ui/view/base/web/js/lib/core/element/element.js
initModules: function () {
    _.each(this.modules, function (name, property) {
        if (name) {
            this[property] = this.requestModule(name);
        }
    }, this);

    if (!_.isFunction(this.source)) {
        this.source = registry.get(this.provider);
    }

    return this;
},

This is the function that sets up the modules default. However, it also has a second job

#File: vendor/magento/module-ui/view/base/web/js/lib/core/element/element.js
if (!_.isFunction(this.source)) {
    this.source = registry.get(this.provider);
}

If the source property of this object is not a javascript function, then Magento will use the string from the provider property to fetch an item from the uiRegistry and assign it to source.

This seems straight forward – but if you search through Magento’s javascript source files you won’t find many with a top level provider property.

This is where Magento_Ui/js/core/app and Magento_Ui/js/core/renderer/layout enter the picture. You’ll remember from the UI Component series that the Magento_Ui/js/core/app, invoked via an x-magento-init script, uses the Magento_Ui/js/core/renderer/layout module to parse through a large JSON tree of data and use that data to instantiate view models. These view models are almost explicitly uiElement inheriting objects, and the provider property is included in the large JSON tree.

Magento instantiates the view models here

#File: vendor/magento/module-ui/view/base/web/js/core/renderer/layout.js
function initComponent(node, Constr) {    
    var component = new Constr(_.omit(node, 'children'));
    registry.set(node.name, component);
}

The _.omit(node, 'children') contains a JSON data structure that can override the defaults values set in the RequireJS modules. The defaults provide default values for the constructor function, but by passing in our own data when we instantiate the object, we can override these values. This is how Magento uses a server side rendered provider to effect the behavior of the front-end application.

By and large, this provider is used for UI Components, like the grid, that display a data structure. For example, if you’re on the Customer -> All Customers page in the backend and run the following javascript

#File: vendor/magento/module-ui/view/base/web/js/lib/core/element/element.js
reg = requirejs('uiRegistry');
viewModel = requirejs('uiRegistry').
             get('customer_listing.customer_listing.listing_top.fulltext');

console.log(viewModel.provider);
console.log(viewModel.source);

//returns true because the objects are the same object
console.log(viewModel.source === reg.get(viewModel.provider));

You’ll see Magento used the provider string to populate the source property with an item from the registry.

Copyright © Alan Storm 1975 – 2017 All Rights Reserved

Originally Posted: 28th November 2016