Linking properties of UI components
Linking properties implementation
The following properties are used for linking observable properties and methods of UI components:
exports
imports
links
listens
These properties are processed by the initLinks()
method of the uiElement
class which is called at the moment of a component’s instantiation.
Linking properties are set in UI components configuration files: XML, JS or PHP.
List of linking properties
exports
The exports
property is used to copy a local value to some external entity. If the external entity property is anything but a function, it will be set to the value of the local property. If the external property is a function, it will be called with the local properties value as an argument.
If the local value is a ko of io-es5 observable, the external entity will also be updated whenever the local property changes. exports
’s value is an object, composed of the following:
key
: name of the internal property or method that is tracked for changes.value
: name of the property or method that receives the value. Can use string templates.
Example of setting exports
in a component’s .js
file:
1
2
3
4
5
{
'exports': {
'visible': '${ $.provider }:visibility'
}
}
Here visible
is the key
, ${ $.provider }:visibility
is the value
. The value of the local visible
property is assigned to the visibility
property of the provider
component. The latter is changed automatically if the value of visible
changes if the local visible
property is observable (which it isn’t given only the code example above).
Example of setting exports
in a component’s configuration .xml
file:
1
2
3
4
5
6
7
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="exports" xsi:type="array">
<item name="visible" xsi:type="string">sample_config.sample_provider:visibility</item>
</item>
</item>
</argument>
For an example of exports
usage in Magento code see product_form.xml
, line 81
imports
The imports
property is used for tracking changes of an external entity property. imports
’s value is an object, composed of the following:
key
: name of the internal property or method that receives the value.value
: name of the property or method that is tracked for changes. Can use string templates.
Example of using imports
in a component’s .js
file:
1
2
3
4
5
{
'imports': {
'visible': '${ $.provider }:visibility'
}
}
Here the value of the visibility
property of the provider
component is assigned to the local visible
property. If the latter is a ko or ko-es5 observable, the local property is automatically updated if visibility
changes.
Example of using imports
in a component’s configuration .xml
file:
1
2
3
4
5
6
7
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="imports" xsi:type="array">
<item name="visible" xsi:type="string">sample_config.sample_provider:visibility</item>
</item>
</item>
</argument>
For an example of imports
usage in Magento code see product_form.xml
, line 103
links
The links
property is used for cross tracking properties changes: both linked properties are tracked and changing of one results in changing the other. links
’s value is an object, composed of the following:
key
: name of the internal property or method that sends and receives the notifications.value
: name of the property or method that sends and receives the value. Can use string templates.
Example of using links
in a component’s .js
file:
1
2
3
4
5
{
'links': {
'visible': '${ $.provider }:visibility'
}
}
Here the local visible
property is linked with the visibility
property of the provider component. If any of them is a ko or ko-es5 observable and changes, the other is changed automatically. If a non-observable linked property is changed the other is not updated automatically.
Example of using links
in a component’s configuration .xml
file:
1
2
3
4
5
6
7
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="links" xsi:type="array">
<item name="visible" xsi:type="string">sample_config.sample_provider:visibility</item>
</item>
</item>
</argument>
For an example of links
usage in Magento code see text.js
, line 19
listens
The listens
property is used to track the changes of a component’s property. listens
’s value is an object, composed of the following:
key
: name of the observable property or method which is tracked for changes. Can use string templates.value
: name of the internal method or property which listens to the changes.
Example of using listens
in a component’s .js
file :
1
2
3
4
5
{
'listens': {
'${ $.provider }:visibility': 'visibilityChanged'
}
}
Here the local visibilityChanged
property is a method that will be called when the visibility
property of the provider
component changes. It receives the new value as an argument. If the local property is not a function, it will be set to the new value.
The external property has to be an observable in order for listens
to have any effect.
Example of using listens
in a component’s configuration .xml
file:
1
2
3
4
5
6
7
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="listens" xsi:type="array">
<item name="sample_config.sample_provider:visibility" xsi:type="string">visibilityChanged</item>
</item>
</item>
</argument>
For example of listens
usage in Magento code see new_category_form.xml
, line 92
Template strings usage
The options of linking properties can contain template strings in the '${...}'
format. During the component’s initialization, values in this format are processed as template strings using ES6 templates. In browsers that do not support ES6 templates, these values are processed as underscore templates.
So if we put a variable name in '${...}'
, it is processed into a string representation of the variable’s value.
When working with UI components, we often need to use the string representation of a certain property of the UI component. To address a property of the UI component in the scope of this component, the $.someProperty
syntax is used.
As a result, if the component’s property is the variable for the template string, we get notation similar to the following:
1
'${ $.provider }:foo'
If the string would be built at runtime it would be equivalent to this.provider + ':foo'
.
We can also build complex templates strings using this syntax, as follows:
- Using variables from the other component:
1
'${ $.provider }:${ $.dataScope }' // 'provider' is the full name of the other component
- Calling several functions in one string:
1
'${ $.provider }:data.overload': 'overload reset validate'// we call 'overload', 'reset', 'validate'
- Using inline conditions:
1
'${ $.provider }:${ $.customScope ? $.customScope + "." : ""}data.validate': 'validate'