6

I have a UI Element that has children. Is it possible for one UI Element to get the instantiated parent element?

I know there is a property called parentName, but that simply returns a string.

Example code:

{
    "*": {
        "Magento_Ui/js/core/app": {
            "components": {
                "configurator": {
                    "component": "Vendor_Module/js/configurator",
                    "template": Vendor_Module/configurator",
                    "children" : {
                        "price": {
                            "component": "Vendor_Module/js/configurator/price",
                            "template": "Vendor_Module/configurator/price",
                            "displayArea": "price",
                            "price": <?php echo $block->getPrice(); ?>
                        }
                    }
                }
            }
        }
    }
}

Now my js/price.js has a this.parentName, but like I said, it's value is 'configurator'. How can I get the instance of the object so I can access it's properties?

I know traversing down the parent tree is bad design practice, so if anyone knows a different on how I can have multiple UI Components react with eachother, I'd be more than happy to hear them.

3
  • Can't you add the parent as a dependency in your component via Require? Unless I've misunderstood your question that would give you access to the parents object (I think?)
    – Ben Crook
    May 19 '17 at 8:38
  • @BenCrook it gives me the component yes, but what I need is the instantiated component somewhere else on the page. So they can interact with eachother and I can read the variables that are set. Using it as a dependency only allows me to create a new instance. May 19 '17 at 8:44
  • Ah I see, I knew I misunderstood.
    – Ben Crook
    May 19 '17 at 9:03
5

I am not 100% sure it is the right way to do it and not 100% sure it will work for components as containers.

In the past I used this.containers variables to refer parents.

i.e.:

this.containers[0]

Otherwise (and suggested way):
If you need this to make children to communicate with parent you could use an external model class used as singleton and required from both parent and child.

In this way you can store common information or send/receive messages.

In the past I solved this way.

UPDATE with Giel Berkers comment (see below):
Another good approach could be using uiRegistry to share inforamtion between modules.

This approach is suggested when the inforamtion you need to share should be considered global.

8
  • Hm, that second approach sounds a less more like spaghetti code then using the containers-propery. I think I'll go for that approach. Thanks! May 19 '17 at 9:04
  • I totally agree ;) ! It is the same approach used by Magento2 itself in the checkout procedure to share totals. May 19 '17 at 9:05
  • 1
    When in doubt: look at how Magento does it :-). I'm going to use uiRegistry for this one. Seems the most logical choice to share information between objects. May 19 '17 at 9:15
  • If you just need to share simple information that is the best way. My suggestion was for more structured information. In Magento code you can see both approaches. May 19 '17 at 9:17
  • 1
    Check out this page: devdocs.magento.com/guides/v2.2/ui_comp_guide/concepts/… Using imports, exports, links and listens you can create dependencies between ui components (also without hardcoding them in your JS) Oct 11 '17 at 22:19
2

You can use uiRegistry.get(this.parentName) for it.

0

You can also require your specific class through the definition array in your class where you need the parent.

I had the same problem: I can`t get the parent in a child. After some research I came up with this idea:

define([
    'jquery',
    'uiComponent',
    'ko',
    'mage/translate',
    'mage/validation',
    'uiRegistry',
    'Your_Module/js/view/listing/form'
], function ($, Component, ko, $t, validation, registry, form) {
    'use strict';

return Component.extend({

[...]

Where 'Your_Module/js/view/listing/form' is my parent which I needed. Later in the extended Object I can then use the form object to access the parent instance by using it as a function call:

form().anyMethod()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.