Skip to main content

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.

amis-data-scope-data-link

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:

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:

  1. Unnecessary Updates: The current component may not need to respond to changes in the upper-level data, making the refresh operation redundant.
  2. 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.
Introducing the trackExpression Property

To 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 when xxxVariable 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.)