Pass message to root parent from nested embedded view

Hello everyone

I design an embedded view, that nested another level of embedding views by using Flex repeater. (200 elements)
I’d like to pass a message to the root embedded view when the user clicks on each nested embedded view.
The problem is for passing msg between nested embedded view, the scope of msg should be page otherwise it doesn’t work. (view scope doesn’t work here)

The Problem:
If I have several of my components on a single page, every one of them receives this msg with this config.
I need somehow to limit msg for only the root parent and not going upper level.

One solution I think of is using “non-repeated random ID” for each component and pass to nested view and use it back to root to distinguish the component.
The problem is here the flex repeater has a lot of elements and passing it to all of them is not very efficient and also on each msg, every instance should run to check this ID which is a burden on the server.

I remember from Vision we can target property on the other window in python script from nested window. Is this also possible in Perspective?
Is there a better way for this?

I’m going to start with saying that we already have an open feature request to provide an onInstanceClick event for Flex Repeaters (much like View Canvas has) which would make it really easy to just have the FlexRepeater update a prop or param whenever an instance is clicked. That doesn’t help you now though, so what do you do?

I think you only have two avenues available to you right now, and you already mentioned one of them.

  1. Supply each Embedding component a unique name or custom property value and pass that value to each child, so that the instances can pass it as part of the payload. Then, your Embedded View will need to compare that part of the payload against its own name/property to verify it’s the intended recipient.
  2. Instead of passing some comparison variable, why don’t you just use different handlers for the two embedding components, and pass the handler name to each of the children? That way you don’t have to worry about scope or performing any comparison.
1 Like

I like the idea behind this, but practically I don't think this would work as a message handler type is fixed. It would mean moving the message handler outside of the template view and into each template view instance, thus defeating the purpose of a template.

Looking forward to the new onInstanceClick function though!

1 Like

The “listener” is defined (and hard-coded) on the Embedding component, but the “broadcast” can supply the handler as a parameter:

system.perspective.sendMessage(self.params.messageHandlerName, payload={'something': 'Yo'}, scope='page')

But the message handler name (message type) always has to be the same though right? since the listener's message type is hardcoded. Or am I missing something?

1 Like

For item 2, as @nminchin said the message handler type is fix and hard coded. So may having binding for message handler type is nice feature.

Also, if it is possible having new scope called parent is also nice for perspective message handler.

Actually I have five of this component in a single page, each have 150 elements in each of them. So solution 1 is really burden on gateway.

So, with this limitation do you have any other solutions?

1 Like

Say you have five Embedded View components, which each have 150 instances within them. Configure a different Message Handler for each of the Embedded View components, like HANDLER1 - HANDLER5. Then pass the handler name down to each of the instances within their params

props: {
    instances: [
        {
            messageHandlerName: "HANDLER1"
        }
    ]
}

Then the instances of that Embedded View can all use the SAME code with the parameterized handler broadcast:

system.perspective.sendMessage(self.params.messageHandlerName, payload={'something': 'Yo'}, scope='page')

Notice that since the messageHandlerName param is unique to the Embedded Views, only the “parent” is configured to hear the message.

Alternatively, you could use outgoing params to pass some sort of flag or value back up the parameter chain. So when an instance is clicked, it toggles some outgoing param. The Fex Repeater should then have a custom property bound to instances, and it should include a transform that iterates or uses list comprehension to wait until any of its instances has toggled that flag. When that happens, the Flex Repeater should in turn trigger some outgoing param up to the Embedded View.

What I don’t understand here is if we have 5 instances of the same embedded view that nested other levels of embedded view, how can I define message type differently for each top-level instance? ( I mean parent)
The message handler is hardcoded for the message type.
Could you show us a screenshot of how can I make the message handler dynamic?

For a better understanding of what I deal with, imagine if we want to recreate Pie chart with selection.data property.
Each time user clicks on the Pie chart element, that element sends its ID, name, etc to the top-level parent internally.
Now imagine we have 5 instances of this Pie chart in a single dashboard. Each Pie Chart first has to have a unique ID internally.
Secondly, Pie Chart elements are embedded views.
This is what I want to recreate with an embedded view.

You won’t be able to dynamically set the nested handler - only the top-level Embedded View will be able to modify the handler.