Expression Service
In Oinone Kunlun, many component properties support "expression" configuration. This article will introduce detailed content related to "expressions".
Ⅰ. Overview
You can use Expression.run anywhere to execute an expression and get its calculation result. The specific function signature is as follows:
export interface ExpressionRunParam {
activeRecords: Record<string, unknown>[];
rootRecord: Record<string, unknown>;
openerRecord: Record<string, unknown>;
scene: string | null;
activeRecord?: Record<string, unknown> | null;
parentRecord?: Record<string, unknown> | null;
}
export class Expression {
public static run<T>(param: ExpressionRunParam, expression: string, errorValue?: T): T | string | undefined;
}ExpressionRunParam is the built-in context parameter provided when the expression is executed. The specific meanings are as follows:
- activeRecords: Currently activated data source.
- rootRecord: Root data source.
- openerRecord: Form data source used in the pop-up window. (For example, when opening a pop-up window, the form data can be obtained in the pop-up window)
- scene: Scene
Key. Usually theViewAction#nameattribute corresponding to the current page. - activeRecord: The first object of the currently activated data source.
- parentRecord: Parent data source.
Ⅱ. Using Expressions in Widget Components
Normally, when using the expression service, we do not directly call it in the component, but encapsulate it twice according to the actual usage scenario of the current component. The passing of context parameters will be uniformly managed by this method. Take the built-in executeExpression method in ActionWidget as an example:
public executeExpression<T>(expression: string, errorValue?: T): T | string | undefined {
const activeRecords = this.activeRecords || [];
const scene = this.scene;
return Expression.run(
{
activeRecords,
rootRecord: this.rootData?.[0] || {},
openerRecord: this.openerActiveRecords?.[0] || {},
scene,
activeRecord: activeRecords[0] || {},
parentRecord: this.parentViewActiveRecords?.[0] || []
} as ExpressionRunParam,
expression,
errorValue
);
}When we use expressions, we only need to pass the expression:
@Widget.Reactive()
public get disabled() {
const dslDisabled = this.getDsl().disabled;
if (isNil(dslDisabled)) {
return false;
}
const disabled = BooleanHelper.toBoolean(dslDisabled);
if (disabled != null) {
return disabled;
}
return this.executeExpression(dslDisabled, false);
}- Get the
disabledattribute fromDSL. - When not configured, the default is
false. - When configured as a
Booleantype, the corresponding value is directly returned. - For other types, calculate according to the expression; if an exception occurs in the expression calculation, the default is
false.
Note:
The data type of all attributes obtained in DSL is: string | number | boolean | undefined
In this example, the Number type can have the meaning of Boolean in JavaScript, so there is no need to process it.
Ⅲ. Expression Syntax
(Ⅰ) Object Property Access
In an expression, you can use "." to access object data level by level. For example:
activeRecord.partner.nameWhen the expression is passed an object with such a structure, the value of "name" can be obtained normally after the expression is executed:
{
"acitveRecord": {
"partner": {
"name": "Name"
}
}
}(Ⅱ) Array Property Access
In an expression, use the LIST_GET function to get an object according to the array index and continue to get values from the object. For example:
LIST_GET(activeRecords, 0).partner.nameWhen the expression is passed an object with such a structure, the value of "name" can be obtained normally after the expression is executed:
{
"acitveRecords": [
{
"partner": {
"name": "Name"
}
}
]
}Note:
For more content about built-in functions, please refer to: Function API
(Ⅲ) Use of Literals
In an expression, you can use the "+" operator to represent string concatenation, which has exactly the same function as the built-in function JOIN:
// Use the "+" operator to concatenate strings
activeRecord.name + "_demo"
// Use the JOIN function to concatenate strings
JOIN(activeRecord.name, "_demo")Side Effects of the "+" Operator
Since the "+" operator has two semantics: numeric addition calculation and string concatenation, we cannot accurately identify the numeric type through the JavaScript type (sometimes numbers are stored as strings). Therefore, when the expression calculation finds that both the left and right sides of the "+" operator are numbers, addition calculation will be performed:
// Recognized as numeric addition calculation, the result is: 3
"1" + "2"In this case, when you need to use the function of concatenating strings accurately, you can use the JOIN function to concatenate:
// Use the JOIN function to concatenate strings, the result is: "12"
JOIN("1", "2")