Data Scope and Data Chain
Basic Concepts: Data Scope and Data Chain
The concepts of Data Scope and Data Chain are among the most important in AMIS. They ensure consistency and predictability in data interaction and management between components. It can be likened to the concept of scope in programming, where the data scope of a parent component is visible to its child components, similar to how variables are visible within their scope. Here is a simplified explanation:
In AMIS, components are organized into a tree-like structure, and each component can have its own data scope. A data scope can be understood as a container for storing data, determining which data is available in specific parts of the component tree.
Reference document: AMIS Data Scope, Data Chain
Components with Data Scope
- App
- Combo
- Cards
- Chart
- CRUD
- CRUD2
- Dialog
- Drawer
- List
- Page
- PaginationWrapper
- Service
- Wizard
- InputArray
- Table
- Table2
1. Initializing the Data Scope
The data scope can be initialized in two main ways:
Component Initialization Interface
Assign an initApi property to the component, instructing AMIS to fetch data from a specified endpoint and populate the component's data scope with the response. Components can obtain basic data through the specified initApi, assuming we have an API endpoint: /amis/api/initData
{
"type": "page",
"initApi": "/amis/api/initData",
"body": "Hello ${text}"
}
References:
- Page component: Page Component, Initialize Data
- API: AMIS API
Explicit Data Property Configuration
Static data comes from the data configured when defining the component. For example, when defining a Page component, the data property can define data to be used by child components
{
"type": "page",
"body": [
{
"type": "tpl",
"tpl": "I am ${name}, ${age} years old",
"id": "u:3a18f25bc36b"
}
],
"data": {
"age": 18,
"name": "Li Gang"
},
"id": "u:randomid"
}
When both initialization interface and data property are configured, the data scope will merge the data property values and the data returned by the initialization interface.
2. Updating the Data Scope
Certain interactions or behaviors of some components will update the current component's data scope:
{
"type": "page",
"body": {
"type": "form",
"api": "/amis/api/mock2/form/saveForm",
"body": [
{
"type": "input-text",
"name": "name",
"label": "Name:"
},
{
"type": "input-text",
"name": "age",
"label": "Age:"
},
{
"type": "static-tpl",
"tpl": "The generated id is: ${id}"
}
]
}
}
The /api/saveForm interface will save the data submitted by the current form and return the id generated by the backend service to the frontend, in the following format;
{
"status": 0,
"msg": "Saved successfully",
"data": {
"id": 1
}
}
At this point, AMIS will merge the data with the current form component's data scope, and the static-tpl component in the form will display the id as 1.
Components with similar features include Formula, etc.
3. Updating the Data Chain
In AMIS, updates to the top-level data scope trigger synchronous updates of child components with data scopes to ensure data consistency. However, such comprehensive updates may bring unnecessary performance overhead. For example, updating only the top-level name
variable would cause all child components to refresh. To optimize this process, AMIS by default detects changes in two levels of data scope (direct upper and upper-upper) to decide whether to update the current layer's data. There are two potential issues with this mechanism:
- Unnecessary Updates: The current component may not need to respond to changes in the upper-level data, making the refresh operation redundant.
- Insufficient Updates: The current component may need to respond to changes in higher-level data, but the default detection mechanism cannot obtain the latest value.
trackExpression
PropertyTo address these issues, starting from version 3.2.0, AMIS introduced the trackExpression
property, allowing developers to actively configure the upper-level data that the component needs to pay attention to. Thus, we can:
- Set
trackExpression
to"none"
to indicate that the current component does not track any data changes. - Set
trackExpression
to"${xxxVariable}"
to specify that the current component's data chain should be updated whenxxxVariable
changes.
trackExpression
supports complex expression syntax, allowing monitoring of multiple variables (such as "${xxx1},${xxx2}"
) or writing conditional expressions (such as "${xxx ? xxx : yyy}"
). AMIS will decide whether to update the data chain based on the result of the expression calculation.
Considerations:
- Avoid using random functions or the current time in expressions, which would lead to different results each time and thus unnecessary updates to the data chain.
- If the variable is an array or object, it is recommended to convert it to a JSON string (such as
${xxxObject | json}
) to improve the accuracy of change detection. - Since
trackExpression
is used to monitor upper-level data, it should not reference the current layer's data variables in the expression.
4. Others
URL Parameters
Query parameters in the URL will enter the top-level data scope. For example, if the micro-page is on the page https://abcd.com/yyyyy?bookId=29891, then bookId will be at the top of the data scope. (The top-level data scope also means that all components can use the bookId variable.)