Purpose of this property type

The 'component' property type can be used by web components to nest other web components inside them.

The nested components can be regular components - based of the parent's environment (foundset, ...) or linked to a .spec defined 'foundset' typed property, in which case they will receive data corresponding to records in that foundset.

The 'component' property value client side receives in JS all it needs to 'instantiate' a child web component and make it operational just like a normal form level web component.

Currently such child components will be available Servoy server side JS scripting in form.elements - as any other web components in the form at root level.

Servoy Developer's form editor handles adding/setting/removing child components through this property type behind-the-scenes. So the property itself will not appear in the properties view during development.

When component is not linked to a foundset

A child component that is not linked to another foundset, so it is only nested within another web component is easy to implement.

Let's say you want to create a component that has 2 child web components.

.spec file

    "model":
    {
        (...)
        "childComponent1": { "type": "component" },
        "childComponent2": { "type": "component" },
		(...)
    },

So our component's spec file defines two properties of type "component" for the two child components it wants to have. Note: some containers might want a variable number of child components - that can be done using a property of type 'component[]'.

html template

<div (...)>
    (...)
    <svy-component-wrapper component-property-value="model.childComponent1"></svy-component-wrapper>
    <svy-component-wrapper component-property-value="model.childComponent2"></svy-component-wrapper>
    (...)
</div>

The template of our parent component directive uses the svy-component-wrapper directive that Servoy provides to easily integrate child web components in the right place.

That's all you have to do; no special scripting is required.

NOTE: do not try directly <svy-component-wrapper component-property-value="model.childComponent1"/> as that will not work.

Advanced usage of non-foundset-linked components

For advanced usage (most will probably never want to do this), if the parent component needs for some reason to manipulate child model/behavior, it can do that by specifying each attribute to be set on child separately - and it can intercept 'component' property content or provide there whatever it wants instead of directly the 'component' property type content. The template snippet below will produce identical results as the one above that only sets the "component-property-value" attribute:

<svy-component-wrapper tagname="model.childComponent1.componentDirectiveName"
     name="model.childComponent1.name"
     svy-model="model.childComponent1.model"
     svy-api="model.childComponent1.api"
     svy-handlers="model.childComponent1.handlers"
     svy-servoyApi="model.childComponent1.servoyApi">
</svy-component-wrapper>

Child components linked to a foundset

Portals, table view, list view use this. They have a set of 'component' properties (an array of them) which is linked to a foundset. The components represent a "row" logically. In this case the browser JS value for the properties will contain the needed data to build up one set of child components for each row in the 'foundset' typed property's viewport. See the 'foundset' property type page for more info about it's usage.

When components linked to a foundset are requested by a custom web component, that component will need to deal itself with how it creates child components in the browser (how will it visually display separate rows/columns of the foundset as child components) and how it links model/behavior between them and the 'component' typed property/properties. The 'component' typed property provides all that is needed to make that work.

.spec file

    "model":
    {
        (...)
        "myFoundset" : "foundset",

        "childElement" : { "type" : "component", "forFoundset": "myFoundset" }, // or
        "childElements" : { "type" : "component[]", "elementConfig" : {"forFoundset": "myFoundset"} }, 
		(...)
    },

Above we defined 2 properties: 'childElement" for one child component linked to a foundset, and 'childElements' as an array of child components linked to the given foundset. The foundset is specified using "forFoundset" configuration value. In case of the array property - the configuration value is specified for each element of the array using "elementConfig".

Foundset linked component property value in browser

In browser js, a component property value that is linked to a foundset has the following content (example contents of a child text field in a portal parent):

childElement: {
    "componentDirectiveName": "servoydefault-textfield",
    "name": "shipname",
    "forFoundset": {
        "recordBasedProperties": ["dataProviderID"]
    },
    "model": {
        "enabled": true,
        "text": "Ship Name",
        "visible": true,
        "tabSeq": 0,
        (...)
    },
    "modelViewport": [{ "_svyRowId": ".null;5.10643;_0", "dataProviderID": "Alfreds Futterkiste" },
                      { "_svyRowId": ".null;5.10692;_1", "dataProviderID": "Alfred's Futterkiste 2" },
                      (...)]
    "handlers": {
        "onActionMethodID": function(args, rowId),
        (...)
    },
    "api": {
        "getSelectedText": function(),
        (...)
    },
    "servoyApi": {
        "startEdit": function(propertyName, rowId)
    },
    "apply": function(propertyName, componentModel, rowId)
}

These contents can be used to generate what's needed and provide it to a "svy-component-wrapper" (see usage above) or can be used with other angular components out there that generate their own templates for individual components per record (such as uiGrid).

Runtime property access

Since Servoy 8.0.3 , component type is scriptable. Type can be accessed like: 

elements.mycomponent.childElements.mybean.beanProperty

Mycomponent is the name of the component which contains a childElements property of type component or component[] . From there, you can access the component inside type via name or index (if type is an array). Then you can access or assign properties of the mybean type.