

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# JavaScript 用于在 App Studio 中编写表达式
<a name="expressions"></a>

在 AWS App Studio 中，您可以使用 JavaScript 表达式来动态控制应用程序的行为和外观。单行 JavaScript 表达式用双花括号、`{{ }}`、编写，可用于各种上下文，例如自动化、用户界面组件和数据查询。这些表达式在运行时进行求值，可用于执行计算、操作数据和控制应用程序逻辑。

App Studio 为三个 JavaScript 开源库提供原生支持：Luxon、UUID、Lodash 以及 SDK 集成，用于检测应用程序配置中的 JavaScript 语法和类型检查错误。

**重要**  
App Studio 不支持使用第三方库或自定义 JavaScript 库。

## 基本语法
<a name="expressions-basic-syntax"></a>

JavaScript 表达式可以包括变量、文字、运算符和函数调用。表达式通常用于执行计算或评估条件。

请参阅以下示例：
+ `{{ 2 + 3 }}`将评估为 5。
+ `{{ "Hello, " + "World!" }}`将评估为 “你好，世界！”。
+ `{{ Math.max(5, 10) }}`将评估为 10。
+ `{{ Math.random() * 10 }}`返回介于 [0-10) 之间的随机数（含小数）。

## 插值
<a name="expressions-interpolation"></a>

也可以使用 JavaScript 在静态文本中插入动态值。这是通过将 JavaScript 表达式用双大括号括起来实现的，如下例所示：

```
Hello {{ currentUser.firstName }}, welcome to App Studio!
```

在此示例中，`currentUser.firstName`是一个 JavaScript 表达式，用于检索当前用户的名字，然后将其动态插入到问候消息中。

## 联接
<a name="expressions-concatenation"></a>

您可以使用中的`+`运算符连接字符串和变量 JavaScript，如下例所示。

```
{{ currentRow.FirstName + " " + currentRow.LastName }}
```

此表达式将`currentRow.FirstName`和`currentRow.LastName`的值组合在一起，中间有一个空格，从而得出当前行的全名。例如，如果`currentRow.FirstName`是`John`、`currentRow.LastName`是`Doe`，则表达式将解析为`John Doe`。

## 日期和时间
<a name="expressions-date-time"></a>

JavaScript 提供了用于处理日期和时间的各种函数和对象。例如：
+ `{{ new Date().toLocaleDateString() }}`：以本地化格式返回当前日期。
+ `{{ DateTime.now().toISODate() }}`：以 YYYY-MM-DD格式返回当前日期，以用于 “日期” 组件。

### 日期和时间比较
<a name="expressions-date-time-comparison"></a>

使用诸如`=`、、`>``<``>=`、或之类的运算符`<=`来比较日期或时间值。例如：
+ `{{ui.timeInput.value > "10:00 AM"}}`: 检查时间是否在上午 10:00 之后。
+ `{{ui.timeInput.value <= "5:00 PM"}}`: 检查时间是否在下午 5:00 或之前。
+ `{{ui.timeInput.value > DateTime.now().toISOTime()}}`：检查时间是否在当前时间之后。
+ `{{ui.dateInput.value > DateTime.now().toISODate()}}`：检查日期是否早于当前日期。
+ `{{ DateTime.fromISO(ui.dateInput.value).diff(DateTime.now(), "days").days >= 5 }}`：检查该日期是否距离当前日期至少有 5 天。

## 代码块
<a name="expressions-code-block"></a>

除了表达式之外，您还可以编写多行 JavaScript 代码块。与表达式不同，代码块不需要花括号。相反，您可以直接在 JavaScript 代码块编辑器中编写代码。

**注意**  
在计算表达式并显示其值时，运行代码块并显示其输出（如果有）。

## 全局变量和函数
<a name="expressions-global-variables-functions"></a>

App Studio 提供对某些全局变量和函数的访问权限，这些变量和函数可以在 JavaScript 表达式和代码块中使用。例如，`currentUser`是一个表示当前登录用户的全局变量，您可以访问诸如检索用户角色之类`currentUser.role`的属性。

## 引用或更新 UI 组件值
<a name="expressions-UI-component-values"></a>

您可以在组件和自动化操作中使用表达式来引用和更新界面组件值。通过以编程方式引用和更新组件值，您可以创建响应用户输入和数据更改的动态交互式用户界面。

### 引用 UI 组件值
<a name="expressions-UI-component-values-referencing"></a>

您可以通过访问用户界面组件中的值来实现动态行为，从而创建交互式和数据驱动的应用程序。

通过在表达式中使用`ui`命名空间，可以在同一页面上访问用户界面组件的值和属性。通过引用组件的名称，您可以检索其值或根据其状态执行操作。

**注意**  
`ui`命名空间将仅显示当前页面上的组件，因为组件的作用域仅限于其各自的页面。

在 App Studio 应用程序中引用组件的基本语法是:`{{ui.componentName}}`.

以下列表包含使用`ui`命名空间访问界面组件值的示例：
+ `{{ui.textInputName.value}}`: 表示名为的文本输入组件的值*textInputName*。
+ `{{ui.formName.isValid}}`：根据您提供的验证标准，检查名*formName*为的表单中的所有字段是否有效。
+ `{{ui.tableName.currentRow.columnName}}`：表示名为的表组件当前行中特定列的值*tableName*。
+ `{{ui.tableName.selectedRowData.fieldName}}`：表示名为的表组件中选定行中指定字段的值*tableName*。然后，您可以追加诸如 `ID` (`{{ui.tableName.selectedRowData.ID}}`) 之类的字段名称，以引用选定行中该字段的值。

以下列表包含更多引用组件值的具体示例：
+ `{{ui.inputText1.value.trim().length > 0}}`：在修剪任何前导或尾随空格后，检查*inputText1*组件的值是否具有非空字符串。这对于根据输入文本字段的值验证用户输入 enabling/disabling 或其他组件非常有用。
+ `{{ui.multiSelect1.value.join(", ")}}`: 对于名为的多选组件*multiSelect1*，此表达式将所选选项值的数组转换为逗号分隔的字符串。这对于以用户友好的格式显示所选选项或将选择传递给其他组件或自动化非常有用。
+ `{{ui.multiSelect1.value.includes("option1")}}`：此表达式检查该值*option1*是否包含在*multiSelect1*组件的选定选项数组中。如果*option1*选择则返回 true，否则返回 false。这对于有条件地渲染组件或根据特定选项选择采取操作非常有用。
+ `{{ui.s3Upload1.files.length > 0}}`：对于名为的 Amazon S3 文件上传组件*s3Upload1*，此表达式通过检查文件数组的长度来检查是否已上传任何文件。根据文件是否已上传，它可能对 enabling/disabling 其他组件或操作很有用。
+ `{{ui.s3Upload1.files.filter(file => file.type === "image/png").length}}`：此表达式筛选*s3Upload1*组件中已上传文件的列表，使其仅包含 PNG 图像文件，并返回这些文件的数量。这可能有助于验证或显示有关上传文件类型的信息。

### 更新 UI 组件值
<a name="expressions-UI-component-values-updating"></a>

要更新或操作组件的值，请在自动化`RunComponentAction`中使用。以下是可用于更新使用`RunComponentAction`操作命名的*myInput*文本输入组件值的语法示例：

```
RunComponentAction(ui.myInput, "setValue", "New Value")
```

在此示例中，该`RunComponentAction`步骤调用*myInput*组件上的`setValue`操作，并传入新值*New Value*。

## 处理表格数据
<a name="expressions-table-data"></a>

您可以访问表数据和值以执行操作。您可以使用以下表达式来访问表数据：
+ `currentRow`：用于访问表中当前行的表数据。例如，设置表格操作的名称，将行中的值发送到从操作启动的自动化，或者使用表中现有列中的值来创建新列。
+ `ui.tableName.selectedRow`和`ui.tableName.selectedRowData`都用于访问页面上其他组件的表数据。例如，根据所选行在表格外设置按钮的名称。返回的值相同，但`selectedRow`和之间的区别`selectedRowData`如下：
  + `selectedRow`：此命名空间包括每个字段的列标题中显示的名称。`selectedRow`在引用表中可见列中的值时，应使用。例如，如果您的表中有一个自定义列或计算列，但该列在实体中不作为字段存在。
  + `selectedRowData`：此命名空间包括实体中用作表源的字段。您应该使用`selectedRowData`来引用实体中的一个值，该值在表格中不可见，但对于应用程序中的其他组件或自动化很有用。

以下列表包含在表达式中访问表数据的示例：
+ `{{ui.tableName.selectedRow.columnNameWithNoSpace}}`：返回表中选定行中该*columnNameWithNoSpace*列的值。
+ `{{ui.tableName.selectedRow.['Column Name With Space']}}`：返回表中选定行中该*Column Name With Space*列的值。
+ `{{ui.tableName.selectedRowData.fieldName}}`：返回表格中选定行中*fieldName*实体字段的值。
+ `{{ui.tableName.selectedRows[0].columnMappingName}}`：从同一页面上的其他组件或表达式中引用选定行的列名。
+ `{{currentRow.firstName + ' ' + currentRow.lastNamecolumnMapping}}`：连接多列中的值以在表中创建新列。
+ `{{ { "Blocked": "🔴", "Delayed": "🟡", "On track": "🟢" }[currentRow.statuscolumnMapping] + " " + currentRow.statuscolumnMapping}}`：根据存储的状态值自定义表中字段的显示值。
+ `{{currentRow.colName}}`、`{{currentRow["First Name"]}}``{{currentRow}}`、或`{{ui.tableName.selectedRows[0]}}`：在行操作中传递被引用的行的上下文。

## 访问自动化
<a name="expressions-automations"></a>

你可以在 App Studio 中使用自动化来运行服务器端逻辑和操作。在自动化操作中，您可以使用表达式来处理数据、生成动态值以及合并先前操作的结果。

### 访问自动化参数
<a name="expressions-automations-parameters"></a>

您可以将来自用户界面组件和其他自动化的动态值传递到自动化中，从而使其可重复使用且灵活。这是使用`params`命名空间的自动化参数完成的，如下所示：

`{{params.parameterName}}`：引用从用户界面组件或其他来源传递到自动化的值。例如，`{{params.ID}}`将引用名为的参数*ID*。

#### 操纵自动化参数
<a name="expressions-automations-parameters-manipulate"></a>

您可以使用 JavaScript 来操作自动化参数。请参阅以下示例：
+ `{{params.firstName}} {{params.lastName}}`：连接作为参数传递的值。
+ `{{params.numberParam1 + params.numberParam2}}`：添加两个数字参数。
+ `{{params.valueProvided?.length > 0 ? params.valueProvided : 'Default'}}`：检查参数是否不为空或未定义，且长度是否为非零。如果为 true，则使用提供的值；否则，设置默认值。
+ `{{params.rootCause || "No root cause provided"}}`：如果`params.rootCause`参数为 false（空、未定义或空字符串），请使用提供的默认值。
+ `{{Math.min(params.numberOfProducts, 100)}}`：将参数的值限制为最大值（在本例中为`100`）。
+ `{{ DateTime.fromISO(params.startDate).plus({ days: 7 }).toISO() }}`：如果`params.startDate`参数为`"2023-06-15T10:30:00.000Z"`，则此表达式的计算结果将为`"2023-06-22T10:30:00.000Z"`，即开始日期一周后的日期。

### 访问先前操作的自动化结果
<a name="expressions-automations-results"></a>

自动化允许应用程序运行服务器端的逻辑和操作，例如查询数据库 APIs、与之交互或执行数据转换。`results`命名空间提供对同一自动化中先前操作返回的输出和数据的访问权限。关于访问自动化结果，请注意以下几点：

1. 您只能访问同一个自动化中先前自动化步骤的结果。

1. 如果您有按该顺序命名的*action1*操作，则*action1*无法引用任何结果，*action2*只能访问`results.action1`。*action2*

1. 这也适用于客户端操作。例如，如果你有一个使用`InvokeAutomation`操作触发自动化的按钮。然后，您可以设置一个导航步骤，`results.myInvokeAutomation1.fileType === "pdf"`其`Run If`条件是，如果自动化显示文件是 PDF，则使用 PDF 查看器导航到页面。

以下列表包含使用`results`命名空间访问先前操作的自动化结果的语法。
+ `{{results.stepName.data}}`：从名为的自动化步骤中检索数据数组*stepName*。
+ `{{results.stepName.output}}`：检索名为的自动化步骤的输出*stepName*。

访问自动化步骤结果的方式取决于操作的类型及其返回的数据。不同的操作可能会返回不同的属性或数据结构。下面是一些常见的示例：
+ 对于数据操作，您可以使用访问返回的数据数组`results.stepName.data`。
+ 对于 API 调用操作，您可以使用访问响应正文`results.stepName.body`。
+ 对于 Amazon S3 操作，您可以使用访问文件内容`results.stepName.Body.transformToWebStream()`。

请参阅文档，了解您正在使用的特定操作类型，以了解它们返回的数据的形状以及如何在`results`命名空间中访问这些数据。以下列表包含一些示例
+ `{{results.getDataStep.data.filter(row => row.status === "pending").length}}`：假设*getDataStep*是一个返回数据行数组的`Invoke Data Action`自动化操作，则此表达式会筛选数据数组，使其仅包括状态字段等于的行`pending`，并返回筛选数组的长度（计数）。这对于根据特定条件查询或处理数据非常有用。
+ `{{params.email.split("@")[0]}}`：如果`params.email`参数包含电子邮件地址，则此表达式会在 @ 符号处拆分字符串，并返回 @ 符号之前的部分，从而有效地提取电子邮件地址的用户名部分。
+ `{{new Date(params.timestamp * 1000)}}`：此表达式采用 Unix 时间戳参数 (`params.timestamp`) 并将其转换为 JavaScript Date 对象。它假设时间戳以秒为单位，因此将其乘以1000，将其转换为毫秒，这是构造函数所期望的格式。`Date`这对于在自动化中处理日期和时间值非常有用。
+ `{{results.stepName.Body}}`: 对于名为的`Amazon S3 GetObject`自动化操作*stepName*，此表达式会检索文件内容，用户界面组件（例如 I **mag** e 或 **PDF Viewer**）可以使用这些内容来显示检索到的文件。请注意，需要在**自动化的自动化输出**中配置此表达式才能在组件中使用。