Child pages
  • Component (child) property type
Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 9 Next »

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):

Browser side provided property content in model
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).

  • componentDirectiveName: also present when not linked to a foundset; read-only; the directive tag name of the child web component.

  • name: also present when not linked to a foundset; read-only; the name (property) of the web component.
  • forFoundset.recordBasedProperties: not present when not linked to a foundset; read-only; a list of child component property names that are delivered for each record in the foundset viewport (these properties have different values for each record and will be available in modelViewport).
  • model: also present when not linked to a foundset; read-write; properties of the child component that are the same for all records in the foundset's viewPort.
  • modelViewport: not present when not linked to a foundset; read-write; model properties of the child component that have different values for each record in the foundset; this array's indexes correspond directly to the indexes of the linked 'foundset' type property's 'viewPort'; it's contents change when the 'foundset' property's viewPort change. See foundset property type documentation for more about how the viewPort is controlled.
    handlers: also present when not linked to a foundset; read-only; whatever handlers the web component has attached (chosen by developer at design-time). See discussion about 'rowId' from servoyApi.startEdit below 
  • api: also present when not linked to a foundset; read-write; whatever API functions the textfield component provided; initially empty object. When component is linked to a foundset and the server side JS code calls such an API function it should get called in the end on the selected foundset record's child component that represents this component property (there is some support choosing to call on childComponents corresponding to all records, through a forFoundset.apiCallTypes entry, but that is not currently used nor documented here).
  • servoyApi: also present when not linked to a foundset; read-only; Servoy specific API provided to be used with web components.
    • startEdit(propertyName, rowId): provided by the 'component' property; it is used by the child component's svy-autoapply directive (if used by child component) or by custom child component directive code to signal that the editing of that cell has started; as you will probaly have one child component representing this 'component' property value for each record in the foundset's viewPort - startEdit requires receiving a 'rowId' argument to know which record entered edit mode. For example the parent component creates a wrapper startEdit(propertyName) function (closure around the rowId of that record - that is always available in modelViewport as "_svyRowId" that will call the 'component' provided startEdit using that rowId) for each record and feeds it to the corresponding angular component. (the rowId argument is not relevant when using non-foundset linked components)
    • apply(propertyName, componentModel, rowId): also present when not linked to a foundset; read-only; 'componentModel' and 'rowId' are only relevant when the component is linked to a foundset. 'componentModel' is the real object that is given by parent component to the per-record child component at record 'rowId' as model - this is most likely made up of a combination between model and a modelViewport row. See discussion about 'rowId' from servoyApi.startEdit above. Apply pushes a changed dataprovider value of the child component to the record on the server. It is used by svy-autoapply directive or directly by custom child component code.

Runtime property access

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

Scripting access
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.

  • No labels