Perspective .getChildren

Hi All,

Trying to loop through some objects on a perspective view and try to determine the container type. i.e. is it a Flex Container, Coordinate, etc. The following code will loop through the names of all the objects in the view but looking for the object type.

	children = self.view.rootContainer.getChildren() 
	for child in children:
		system.perspective.print(child.name)

Thanks,
Pete

We have not exposed the “type” of a component at this time, and you’re one of the first to inquire about how to do so. If we did provide the type of a Perspective component, would it be useful to you? We haven’t already exposed it because we couldn’t think of a use-case where a user would need to know what type of component they were dealing with through a script.

What are you attempting to do with this script? Perhaps there’s a way to complete your goal without knowing the type.

We’re basically creating a CRUD form with a bunch of embedded views. We’re then going to loop through all of the components to build our insert, update SQL function. Trying to figure out if it is an embedded view and then we can use the path to the embedded view to retrieve the user input values.

One other way around this would be to determine if the child has a props called ‘path’. Only way we could see is with a try function which doesn’t sound proper but I won’t proclaim to be an expert on best practices with python/code in general.

    for child in self.view.rootContainer.getChildren() :
        try:
            path = child.props.path
            params = sql_query_stuff(path)
            child.props.params = params  # or whatever you intend on doing
        except AttributeError:
            # child had no "path" property/attribute, so do something else
2 Likes

Thanks!

That will work… was just a bit leery of what that will do as we have upwards of 500 components on this view but we’ll give it a shot.

This will only look one level deep. If you want to recursively dive into containers you’ll need a whole additional layer of logic.

I have in no way executed this, but you would want something like this:

def write_params(list_or_single_component):
    children = list_or_single_component.getChildren()
    if children is not None and len(children)>0:
        for child in children:
            write_params(child)
    else:
        try:
            path = list_or_single_component.props.path
            params = sql_query_stuff(path)
            list_or_single_component.props.params = params  # or whatever you intend on doing
        except AttributeError:
            pass  # it sounds like you might want this

write_params(self.view.rootContainer)

Here’s what we ended up doing and it works. Thanks for your help:

	def DictCreate(components):
		for component in components:
			try: #if props.path exists that means its an embedded view
				path=component.props.path #check
				if path in ["Page/Embedded/DateFieldFlex","Page/Embedded/DropdownFlex","Page/Embedded/FloatNumberEntryFlex","Page/Embedded/IntegerNumberEntryFlex","Page/Embedded/RadioGroupFlex","Page/Embedded/TextAreaFlex","Page/Embedded/TextFieldFlex"]:
					attribute = component.props.params.Attribute
					system.perspective.print(attribute)
					selectedValue = component.props.params.selectedValue
					attval = {attribute:selectedValue}
					attributes.update(attval)
			except: #if the component isnt a embedded view recursively loop through its children 
				DictCreate(component.getChildren())			
	containers = self.view.rootContainer.getChildren() #define the root container and its children, a series of flex containers
	for container in containers: #loop through the root container, and call the looping function to search through the flex containers for embedded views
		DictCreate(containers)

There’s a minor issue which might creep up: there are other components which have path properties, like the Flex Repeater. Also, I’m not sure how the script is working because there is a variable “attributes” which I don’t see defined, but you seem to be updating it. I’m betting that the generic except is catching the Error and continuing on.

What is the ‘attributes’ variable being used for? I ask because this still seems like an unnecessary process.

Sorry - that script is not generic. It’s specific to the views we are using… We have some custom parameters which we are exposing within the embedded view. - attribute and selectedValue are custom to those vies. The “if path in” statement" makes sure we are only looking into embedded views which are specific to the form components we are interested in.

Okay, that would prevent the Flex Repeater issue, but the “attributes” variable should still be a problem. That “attributes” variable is not defined, so what is the update invocation doing?

Sorry I didnt post the entire script - it is pretty lengthy - just the loop. The attributes object is a dictionary we are instantiating in other places in the script.

Okay, sounds good.

I want to provide a facility to operator to search/find components (i.e. PE001, Conv002 etc.) located on view. Operator will enter a PE or 001 in the text box and then click “find” button provided.

I have refereed below code and able to find the component name located on that view where the find button is located.

But I want to use find button provided on header, which is different view.
Hence, I am trying to pass a “page.props.primaryView” to the below script instead of self.view.

Please advise.

for child in self.view.rootContainer.getChildren() :
        try:
            path = child.props.path
            params = sql_query_stuff(path)
            child.props.params = params  # or whatever you intend on doing
        except AttributeError:
            # child had no "path" property/attribute, so do something else

Thanks in advance!

That’s not going to work.

  1. page.props.primaryView returns a String which is the name of the View resource, ie: “MyOtherView” for a resource located at Perspective/Views/MyOtherView, whereas self.view returns a wrapped View Object (which is why you can access the rootContainer attribute).
  2. Perspective Views have no concept of other Views, so there is no way for a View to search a different View. Perspective Views may ONLY reference their own children.

To do what you’re attempting, you would need to use Perspective’s sendMessage functionality from the View with the “Find” button and then configure a listener on the root node of every other View which itself invokes sendMessage to report back to the primary View. You would also need a configured listener on the primary View to do something with the returned data.

1 Like