M2 system use for read and execute (scriptSelector = 'script[type="text/x-magento-init"]' and dataAttr = 'data-mage-init' ) many js file like vendor/magento/magento2-base/lib/web/mage/apply/main.js and scripts.js and vendor/magento/magento2-base/lib/web/mage /mage.js
you can find vendor/magento/magento2-base/lib/web/mage
in normal case you can declare as virtual :
<script type="text/x-magento-init"> { "[data-role=tocart-form], .form.map.checkout": { "catalogAddToCart": {} } } </script>
or simple :
data-mage-init='{"catalogAddToCart": {}}'
vendor/magento/magento2-base/lib/web/mage/apply/scripts.js is responsible for parses 'script' tags with a custom type attribute and moves it's data
* to a 'data-mage-init' attribute of an elemennt found by provided selector.
* Note: All found script nodes will be removed from DOM
and mage.js take a hand for plugin mage, initialize components on elements :
$.fn.mage = function (name, config) { config = config || {}; this.each(function (index, el) { mage.applyFor(el, config, name); }); return this; };
Here mage.js iterate all element in dom was declared (scriptSelector = 'script[type="text/x-magento-init"]' and dataAttr = 'data-mage-init' ) applied in it . For that it use mage.applyFor(el, config, name) ,
the name in our example is : catalogAddToCart Components path in declared inside requirejs-config.js
config : in our case we passed any configuration you can pass template variable in general or sub child component .
in bottom we Init components inside of dynamically updated elements:
/** * Init components inside of dynamically updated elements */ $('body').on('contentUpdated', function () { if (mage) { mage.apply(); } });
we have here 2 functions apply and applyFor is inside vendor/magento/magento2-base/lib/web/mage/apply/main.js ,ok applyFor is equal init function
/** * Initializes components assigned to a specified element via data-* attribute. * * @param {HTMLElement} el - Element to initialize components with. * @param {Object|String} config - Initial components' config. * @param {String} component - Components' path. */ function init(el, config, component) { require([component], function (fn) { if (typeof fn === 'object') { fn = fn[component].bind(fn); } if (_.isFunction(fn)) { fn(config, el); } else if ($(el)[component]) { $(el)[component](config); } }); }
and apply Initializes components assigned to HTML elements via [data-mage-init].
* @example Sample 'data-mage-init' declaration.
* data-mage-init='{"path/to/component": {"foo": "bar"}}'
it call the function init many time :
apply: function () { var virtuals = processScripts(), nodes = document.querySelectorAll(nodeSelector); _.toArray(nodes) .map(getData) .concat(virtuals) .forEach(function (itemContainer) { var element = itemContainer.el; _.each(itemContainer.data, function (obj, key) { if (obj.mixins) { require(obj.mixins, function () { for (var i = 0, len = arguments.length; i < len; i++) { $.extend(true, itemContainer.data[key], arguments[i](itemContainer.data[key], element)); } delete obj.mixins; init.call(null, element, obj, key); }); } else { init.call(null, element, obj, key); } } ); }); }, applyFor: init };
that is general view of component ...
Comments