Each component encapsulates a specific set of data. For instance, the KoiLabel component holds the text it displays, while the KoiIdButton component stores data that it transmits when the button is clicked. This data can be of various types, may have default values, might allow missing values, or could be mandatory. The structure of the data and any constraints applied to it are defined through a data schema.
A typical data schema is structured as follows:
The schema populates the _properties attribute of an object inherited from KoiData. This attribute is a dictionary containing a collection of objects derived from KoiDataElement. These objects, referred to as data elements, form the basis of the schema.
Data Elements
Objects of the KoiDataElement class define the following properties:
- _localized_name: Stores the user-facing name of the data element in the user's preferred language.
- _allow_empty: Specifies whether the property can accept empty values without being marked invalid.
- _default_value: Represents the default value, which can be overridden by assigning a new default through an attribute.
- _defined: Indicates whether a value has been explicitly provided for the data element.
- _changed: Tracks whether the data value has been modified.
- _valid: Shows whether the current value of the data element is valid.
- _error_code: Stores an error code when the value is invalid.
- _value: Contains the actual value of the data element.
The first three properties derive their values directly from the data schema, i.e., the parameters of the constructor. The remaining properties dynamically reflect the state of the data element, computed based on the input data. Some subclasses of KoiDataElement may introduce additional properties.
The _defined property specifies whether a value has been explicitly set for the element. If the data value is not provided, the default value is used as a substitute. Based on this and guided by the data schema, the component performs automatic transformation and validation of its data.
The _changed property indicates whether the value of the element has been modified. It is updated automatically whenever the value changes through the setValue method. Components use this property to decide whether to react to data changes. Once a response has been processed, the component calls the _setNothingChanged method.
The _valid and _error_code properties function similarly, with _valid indicating the validity of the value and _error_code specifying any error associated with invalid data.
Types of Data Elements
The KoiCom library supports the following data element classes: KoiDataElementList, KoiDataElementListOfIntegers, KoiDataElementInteger, KoiDataElementFloat, KoiDataElementString, KoiDataElementObject, and KoiDataElementBoolean.
Each class has its own distinct features. For instance, the KoiDataElementInteger class includes min and max properties to define permissible value ranges.
These classes are essential for ensuring proper type conversions and value validations. They also manage default values seamlessly, enhancing reliability and consistency in data handling.
Default Values
When an attribute matching the name of a schema element is specified in the component’s tag, the component will attempt to replace the default value defined in the schema with the attribute's value, automatically converting it to the data type specified by the schema.
You can observe this behavior by adding a KoiLabel component to the page and running the following code in the console:
The result will be "This is a label", reflecting the attribute value in the tag. However, if the attribute is not provided in the tag, the result will default to null, as defined in the schema.
Type Conversion
Now let’s take a look at how data type conversion works. Suppose for the DocsMoneyLabel component, which is inherited from KoiLabel, the schema defines the value data element as KoiDataElementInteger.
We add this component to the page with an integer value for the attribute.
Next, we add this component again, but this time with a string value for the attribute.
As you can see, in the second case, the default value (_default_value) for the value element became NaN, whereas in the first case, it was replaced by a number. This means that the component attempted to convert the tag’s value to the data type defined in the schema using the parseInt function, but the conversion failed.
Note that the _defined property remains false for the data elements in both components. This is because we provided the default value through the tags, and the _defined property is responsible for the element's value (_value).
Now let’s try to modify the data value (_value) using the attemptChangeValue method of the component. First, we’ll set it to 100, and then to '200', which is a string that can be converted to a number.
In both cases, we will see number in the console, and the component will display the assigned number. This demonstrates that data type conversion according to the data schema occurs even when setting the data element’s value using the attemptChangeValue method.
If we now check the data element’s properties, we’ll see that the default value hasn’t changed, the _value property is now 200, and the _defined property has become true since the _value property has been assigned a valid value.
Naming of Data Elements
The key in the data schema defines the code name of the data element. The attribute name in the component's tag must match the name of the data element. Therefore, data elements cannot have names that conflict with the names of service tags. In other words, data elements cannot be named id, class, model, etc. This is especially important because in most database tables, the field name is often set as id.