Date: Thu, 28 Mar 2024 09:34:59 +0000 (UTC) Message-ID: <1852863657.10607.1711618499590@911f0a1bad02> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_10606_1317809549.1711618499590" ------=_Part_10606_1317809549.1711618499590 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
The custom object property type can be used by web components to logical= ly group a number of sub-properties (that can be of different types) for ea= sier usage.
Such custom object types are able to send granular updates betwe= en server and client. For example if you change from Rhino one sub= property value (or for more complex element property types - such as 'compo= nent' type - if something changes in only one of the subproperties) then on= ly that change is sent over to the browser/client instead of the whole cust= om object (and the other way around - a subproperty change on client doesn'= t send the full object, just the change to server).
Custom object types are defined in .spec files with a fixed set of subpr= operties as below:
"model": { (...) "myPerson": "person" =09=09(...) }, (...) "types": { "person": { "firstName": "string", "lastName": "string", "photo": "dataprovider" "styleClass" : { "type": "styleclass", "tags": { "scope" :"design" }, "values": ["form-control", "input-sm", "svy-padd= ing-xs"] } } }=20
"pushToServer" .spec settin= g of a custom object property is currently automatically inherited<= /strong> by the sub-properties of that property (so any "p= ushToServer" setting defined on sub-properties of the array will be ingnore= d). That means that for example if you define the custom object prop. to be= "shallow" watched, all it's sub-properties will be shallow watched. If you= don't define pushToServer or define "reject" then the sub-properties of th= at custom object will not be watched inside the browser and any changes to = them will not be sent to the server.
You should not use pushToServer:
A configuration option (that you will most likely never need) for custom= objects (available starting with Servoy 2019.06) is to be able to convert = to null at runtime objects that have any of a set of specific keys set to n= ull at design time ("setToNullAtRuntimeIfAnyOfTheseKeysAreNull": [ = "a", "c" ]):
"model": { =09=09"customObjConvertedToNullIfSpecificKeyIsNull": { "type" : "myCustomOb= j", "setToNullAtRuntimeIfAnyOfTheseKeysAreNull": [ "a", "c" ] } =09=09(...) =09}, "types": { "myCustomObj": { "a": "string", "b": "int", "c": "string" } }=20
For example if in developer properties view you set on this property&nbs= p;{ "a": null, "b": 5, "c": "something"} then, at runtime, the property wil= l be null because "a", one of the "setToNullAtRuntimeIfAnyOfTheseKeysAreNul= l" from .spec, is null. You will probably never need to use this option exc= ept for when you want to create advanced custom components that have arrays= of columns that contain child components (so "model": { "columns": { "= type" : "column[]", "skipNullItemsAtRuntime": true, "elementConfig": { "set= ToNullAtRuntimeIfAnyOfTheseKeysAreNull": [ "columnComponent" ] } }, "types"= : { "column": { "columnHeaderText": "string", "columnComponent": "component= " } }) and where the security settings of a form might not allow some = of the child components (columns) to be visible at runtime - depending on t= he user that logs in. In that case those items in the array would be set to= null automatically by Servoy because the columnComponent is set t= o null automatically if it's not supposed to be visible - and most of the t= imes in this case you want to just get browser-side the columns who's child= components you can show in that array and not worry about nulls and not se= nd anything related to that column to client. See also array type to understand what "elementCon= fig" above does.
The browser value of such a property is a Javascript object containing t= he defined sub-properties:
{ "firstName": "John", "lastName": "Doe", "photo": "https://...." }=20
It is able to send granular updates (so if you change only one property = it will only send that one), depending on it's pushToServer<= /a> configuration.
The server side JS value of such a property is a custom implementation b= ased on Javascript object - so you should be able to use it just like a nor= mal JS object.
There is one difference though. In order to be able to send fine-grained= updates to the client/browser, those values are 'watched'. That means that= whenever you assign a completely new javascript object directly to the pro= perty (or if you assign a new object/array to one of it's sub properties on= any level), that new value (reference) you assign will not be 'watched' di= rectly; you have to take/read it back from the property (which will give yo= u an equivalent 'watched' value) before using it further in code. Or you ca= n access the value of the property directly every time, not kept as a refer= ence.
Whenever you assign a full new value to that property, it will be replac= ed by a copy of it (starting with 8.2), but the prototype of the copy w= ill be the same as the one in the initial value. That means that in th= at prototype you can have for example some methods if you want to build you= r component/service API like that and those methods - if they are defined i= n the prototype - will not be lost in the 'instrumentation' process.
For example:
var newProperty= Value =3D { mySybproperty2 : 10 }; // here you assign a new object to the property elements.myCustomComponent.myObjectProperty =3D newPropertyValue; // here you update the reference that you want to use later in code with th= e 'watched' new value newPropertyValue =3D elements.myCustomComponent.myObjectProperty; (...then later on, maybe during another event handler execution...) // this modification will be detected because it's using the new 'watched' = value you got from elements.myCustomComponent.myObjectProperty after it was= assigned - and the change will be sent to the browser newPropertyValue.mySybproperty1 =3D 5;=20
var newProperty= Value =3D { mySybproperty2 : 10 }; // here you assign a new object to the property elements.myCustomComponent.myObjectProperty =3D newPropertyValue; (...then later on, maybe during another event handler execution...) // this modification will be detected because it's using the property value= directly not through 'newPropertyValue' elements.myCustomComponent.myObjectProperty.mySybproperty1 =3D 5;=20
// DO NOT DO IT= LIKE THIS var newPropertyValue =3D {}; // here you assign a new object to the property elements.myCustomComponent.myObjectProperty =3D newPropertyValue; (...then later on, maybe during another event handler execution...) // this will modify the value in newPropertyValue but myCustomComponent.myO= bjectProperty will not be aware of that to send changes to client/browser newPropertyValue.mySybproperty =3D 5;=20
Custom object properties can be edited at design-time from Servoy Develo= per's properties view and/or using drag and drop operations depending on ty= pe and configuration options. (TODO add more details here)
Custom object types can be nested with array types. This allows you to o= rganize your model's properties better. For example (in .spec file):
"model": { (...) "persons": { "type": "person[]" } =09=09(...) }, (...) "types": { "person": { "firstName": "string", "lastName": "form", "profilePhotos": "dataprovider[]" } }=20
So the 'persons' property at runtime (client side) could look like this:=
[ { "firstName": "John", lastName: "Doe", "profilePhotos": [ "https://....", "https://...." ] }, { "firstName": "Bob", lastName: "Smith", "profilePhotos": [ "https://....", "https://...." ] }, { "firstName": "Jane", lastName: "Doe", "profilePhotos": [ "https://....", "https://...." ] }, ]=20