Skip to content

Instantly share code, notes, and snippets.

@darkogoles1
Last active December 21, 2022 07:13
Show Gist options
  • Save darkogoles1/841d79fc9adba1f20362c1b2c9a24b1c to your computer and use it in GitHub Desktop.
Save darkogoles1/841d79fc9adba1f20362c1b2c9a24b1c to your computer and use it in GitHub Desktop.
Magento 2 Javascript notes (credit to Alan Storm http://alanstorm.com/category/magento-2/)

###RequireJs Modules

  • RequireJs module needs to be defined inside: Your_Module/view/frontend/web/module.js path

  • Simple RequireJs module definition can look like this:

http://collabshot.com/show/A65S78

define([], function () {
    alert('test');
    return {};
});

###X-Magento init

<script type="text/x-magento-init">
    {
        "*" : {
                "Apiworks_Knockout/example" : {}
              }
    }
</script>

  • "*" = like CSS selector on which DOM elements to apply

  • It can be only on specific DOM element, using regular CSS class, id or other selectors

  • It will invoke / call module "Apiworks_Knockout/example" and execute its function

  • {} object is for sending configuration data to RequireJs module's function invoked.

###Magento Javascript Components

http://collabshot.com/show/miG4og


//RequireJs Module definition: 
//Apiworks/Knockout/view/frontend/web/example.js

define([], function () {
    var mageJsComponent = function(config)
    {
        alert("Look in your browser's console");
        console.log(config);
        //alert(config);
    };

    return mageJsComponent;
});


//Code used in template (phtml)
<div id="one" class="foo">Hello World</div>
<div id="two" class="foo">Goodbye World</div>

<script type="text/x-magento-init">
    {
        "*" : {
                "Apiworks_Knockout/example" : {"config":"value"}
              }
    }
</script>

  • Config will be passed to RequireJs Magento module

###Other way to invoke x-magento-init on specific DOM node

  • Invoking same functionality on a specific DOM node:
<div data-mage-init='{"Apiworks_Knockout/example": {"another":"example"}}'>A single div</div>

//Init value should be a valid JSON string which will be parsed by JSON parser

###Initialisation of KnockoutJs in your module:

requirejs(['Magento_Ui/js/lib/ko/initialize'], function(){
    //your program here
});
  • Using Knockout template in your code (phtml):

  • Create a knockout template html file in "Your_Module/view/frontend/web/template/hello.html" like this:

<p data-bind="style:{fontSize:'24px'}">Hello World</p>

  • And then add this in phtml template file:
<div data-bind="template:'Apiworks_Knockout/hello'"></div>

###Data Bind Scopes in Magento:

<li class="greet welcome" data-bind="scope: 'customer'">
    <span data-bind="text: customer().fullname ? $t('Welcome, %1!').replace('%1', customer().fullname) : 'Default welcome msg!'"></span>
</li>

<script type="text/x-magento-init">
{
    "*": {
        "Magento_Ui/js/core/app": {
            "components": {
                "customer": {
                    "component": "Magento_Customer/js/view/customer"
                }
            }
        }
    }
}
</script>
  • The code above is creating a knockoutJs View from "Customer RequireJs module" and it is used above way in phtml.

  • (Magento_Ui/js/core/app RequireJS module is a module that instantiates KnockoutJS view models to use with the scope attribute.)

###How to Debug Ko Views:

**!Important!! There is useful way to debug what each scope (Ko View) contains and here is how to do it: **

<li class="greet welcome" data-bind="scope: 'customer'">
    <pre data-bind="text: ko.toJSON($data, null, 2)"></pre>            
    <!-- ... -->
</li>

###Magento 2 RequireJS Mixins

  • This is the way to override some Magento Js RequireJs module, in this example, we are overriding Magento_Customer/js/view/customer with our hook
//File: app/code/Apiworks/Test/view/base/requirejs-config.js

var config = {
    'config':{
        'mixins': {
            'Magento_Customer/js/view/customer': {
                'Apiworks_Test/hook':true
            }
        }
    }
};    
//File: app/code/Apiworks/Test/view/base/web/hook.js
define([], function(){
    'use strict';    
    console.log("Called this Hook.");
    return function(targetModule){
        targetModule.crazyPropertyAddedHere = 'yes';
        return targetModule;
    };
});
  • If the module in returns a uiClass based object, we can even do this:
define([], function(){
    'use strict';    
    console.log("Called this Hook.");
    return function(targetModule){
        //if targetModule is a uiClass based object!!!! we have function "extend" available
        return targetModule.extend({
            someMethod:function()
            {
                var result = this._super(); //call parent method

                //do your new stuff

                return result;
            }
        });
    };
});

###Wrapping Function Calls

  • The mage/utils/wrapper module allows for functionality similar to a Magento 2 backend around plugin.
  • We are defining our RequireJs module, adding mage/utils/wrapper as requirement
define(['mage/utils/wrapper'], function(wrapper){
    'use strict';    
    
    console.log("Called this Hook.");
    
    return function(targetModule){

        var newFunction = targetModule.someFunction;
        var newFunction = wrapper.wrap(newFunction, function(original){
            //do extra stuff

            //call original method
            var result = original();    

            //do extra stuff                

            //return original value
            return result;
        });

        targetModule.someFunction = newFunction;
        return targetModule;
    };
});    

###Debugging Ko Observables

console.log(objectToHoldMyValue._subscriptions);

->

Object
    change: Array[3]
        0: ko.subscription
        1: ko.subscription
        2: ko.subscription
 
console.log(
    objectToHoldMyValue._subscriptions.change[1].callback
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment