Another javascript debugging snippet for the intrepid Magento 2 javascript programmer. The Magento_Ui/js/core/app
RequireJS module/application/program is an important part of Magento 2’s UI Component system. This is the program that registers KnockoutJS views and makes them available for use in the (custom to Magento 2) Knockout.js scope
binding.
data-bind="scope: some-viewmodel"
While the binding process still remains a bit of a mystery, I’ve recently unearthed a way to view all the available Knockout.js view models.
reg = requirejs('uiRegistry')
reg.get(function(item){
console.log(item.name);
console.log(item);
});
The uiRegistry
RequireJS module (pointing to Magento_Ui/js/lib/registry/registry
by default (located in vendor/magento//module-ui/view/base/web/js/lib/registry/registry.js
)) returns an object that’s a very fancy dictionary/array. This is the object that Magento registers view models to. You can fetch individual view models by name with code like this
reg.get('customer_listing.customer_listing');
Or, as we have above, just pass in a javascript function as a callback to list every item in the registry.
reg = requirejs('uiRegistry')
reg.get(function(item){
console.log(item.name);
console.log(item);
});
The get
method has a number of other ways to query for registered view models – the only documentation for this is in get
’s comments. We’ll leave this as an exercise for the reader.
/**
* Retrieves item from registry which matches specified search criteria.
*
* @param {(Object|String|Function|Array)} query - Search condition (see examples).
* @param {Function} [callback] - Callback that will be invoked when
* all of the requested items are available.
* @returns {*}
*
* @example Requesting item by it's name.
* var obj = {index: 'test', sample: true};
*
* registry.set('first', obj);
* registry.get('first') === obj;
* => true
*
* @example Requesting item with a specific properties.
* registry.get('sample = 1, index = test') === obj;
* => true
* registry.get('sample = 0, index = foo') === obj;
* => false
*
* @example Declaring search criteria as an object.
* registry.get({sample: true}) === obj;
* => true;
*
* @example Providing custom search handler.
* registry.get(function (item) { return item.sample === true; }) === obj;
* => true
*
* @example Sample asynchronous request declaration.
* registry.get('index = test', function (item) {});
*
* @example Requesting multiple elements.
* registry.set('second', {index: 'test2'});
* registry.get(['first', 'second'], function (first, second) {});
*/
The three things you’re probably interested in are a Knockout.js view model’s name, component, and template
reg.get(function(item){
//customer_listing.customer_listing.listing_top.listing_filters.entity_id.to
console.log(item.name);
//Magento_Ui/js/form/element/abstract
console.log(item.component);
//ui/grid/filters/field
console.log(item.template);
});
The name
is a view model’s identifier, and what you’ll use in the scope binding
data-bind="scope: customer_listing.customer_listing.listing_top.listing_filters.entity_id.to"
The component
is the RequireJS module that defines the view model. The template is the (custom to Magento 2) remote Knockout.js template identifier.