APLデータバインディングの評価
Alexa Presentation Language(APL)ドキュメントは、ユーザー提供のデータを取り込み、スタイルやその他の視覚的リソースを組み込み、パラメーターをレイアウトに渡し、データに基づいてレイアウトを条件付きでインフレートさせるために、データバインディングを利用します。ドキュメントでデータバインディングを使用するには、データバインディング式を記述します。これは、${..}という形式の部分文字列が埋め込まれたJSON文字列です。このドキュメントでは、最新バージョンのAPLで、これらの式がAlexaによってどのように評価されるかを説明します。
データバインディング構文の詳細については、データバインディング構文を参照してください。
#{...}構文によるデータバインディングの遅延評価の詳細については、遅延評価を参照してください。
データバインディングアルゴリズム
サンプルのAPLドキュメントに、次のようなTextコンポーネントの定義が含まれているとします。
{
"type": "Text",
"text": "さやには豆が${data.value}粒あります",
"color": "@myBlue",
"fontSize": "${@textSizePrimary * 1.2}"
}
この定義には、評価を必要とする式が3つ含まれています。まず、textにはdata.valueという数値が語句の一部として挿入されています。次に、colorがmyBlueに設定されています。これはユーザー定義のリソースを参照します。最後に、fontSizeがドキュメントのメインテキストの標準サイズよりも1.2倍大きく設定されています。
Alexaは、これらの式を評価するために、式の評価、リソースの参照、型の強制という3ステップのアルゴリズムを使用します。
ステップ1: 式の評価
式の右側が文字列の場合、アルゴリズムは文字列をスキャンしてデータバインディング式(埋め込みの'${}')を探します。1つ以上の埋め込み式が見つかると、文字列全体が抽象構文木(AST)に変換されます。たとえば、上の例のtextは、次のような木構造に変換されます。
Concatenate
String("さやには豆が")
AttributeLookup
Symbol("data")
String("value")
String("粒あります")
ASTは次に、現在のデータバインディングコンテキストを使用して評価されます。データバインディングコンテキストは、キーと値のペアからなるJSONディクショナリーで、値は数値、ブール値、オブジェクト、配列、文字列のいずれかです。+などの演算子により、必要に応じて暗黙的な型変換が行われます。たとえば、データバインディングコンテキストが次のようになっている場合、dataシンボルはオブジェクト{value: 5}を返し、「value」アトリビュートアクセサーは数値5を返します。この3つの要素からなる連結演算には2つの文字列と1つの数値があるため、数値が文字列としてキャストされ、"さやには豆が5粒あります"という文字列値が返されます。
{
"data": {
"value": 5
}
}
ステップ2: リソースの参照
データバインディングの後、文字列値はシステムで定義されたリソースを参照している場合があります。リソース参照は「@」で始まり、ハイフンのない1つの単語で構成されます。リソースは型付けされています。元の例を見ると、Textの色が@myBlueに設定されています。エバリュエーターは、色のリソースから@myBlueという名前のリソースを探します。たとえば、ユーザーが次の形式のリソースブロックを提供したとします。
{
"resources": [
{
"colors": {
"myBlue": "#0033ff"
}
}
]
}
この場合、リソース参照ステージでは「@myBlue」が#0033ffに変換されます。
ステップ3: 型の強制
最終ステップでは、設定された値が正しい型であることを検証します。colorの例では、「#0033ff」という文字列値が返されています。ターゲット値は色であることがわかっているため、この文字列値を、色を表す正しい内部型に変換する必要があります。
初期状態のデータバインディングコンテキスト
新しいAPLドキュメントがインフレートされると、データバインディングコンテキストはクリアされます。クリアな状態のデータバインディングコンテキストには、次の定義済みオブジェクトが含まれています。
| プロパティ | 説明 | 動的 |
|---|---|---|
|
|
画面上でのドキュメントの表示状態です。 |
◯ |
|
|
このドキュメントの実行時間(ミリ秒単位)です。 |
◯ |
|
|
現在のランタイム環境に関する情報です。 |
× |
|
|
ローカル時間(ミリ秒)です。 |
◯ |
|
|
ビルトインの配列関数です。関数呼び出しを参照してください。 |
× |
|
|
ビルトインのログ関数です。関数呼び出しを参照してください。 |
× |
|
|
ビルトインのマップ関数です。関数呼び出しを参照してください。 |
× |
|
|
ビルトインの数学関数です。関数呼び出しを参照してください。 |
× |
|
|
ビルトインの文字列関数です。関数呼び出しを参照してください。 |
× |
|
|
ビルトインの時間関数です。時間関数を参照してください。 |
× |
|
|
UTC時間(ミリ秒)です。 |
◯ |
|
|
現在のデバイスの設定情報です。データバインディングコンテキストのViewportオブジェクトを参照してください。 |
× |
displayState
画面上のドキュメントの現在の状態を示す値を返します。displayStateは、次の表の値のいずれかになります。
| 名前 | 説明 |
|---|---|
|
|
ドキュメントは画面に表示されていません。ドキュメントはティックイベントを生成せず、不規則な間隔でイベントを生成します。正しい動作をするドキュメントは、この状態に入るとすべてのアニメーションを停止します。 |
|
|
ドキュメントは画面上に表示されているか、画面上のほかのコンテンツによって大部分が隠されています。ドキュメントにシステムのメインのフォーカスがない状態です。ドキュメントはティックイベントを生成しますが、ドキュメントアニメーションは最小限に抑える必要があります。 |
|
|
ドキュメントは画面上で前面に表示されています。 |
displayStateプロパティは読み取り専用です。
elapsedTime
elapsedTimeプロパティは、このドキュメントが作成されてからミリ秒単位で単調に増加する時間です。ドキュメントがレンダリングされたときに0から開始し、ドキュメントが画面に表示されている間カウントアップします。elapsedTimeプロパティは、ドキュメントが「フリーズ」しているか、ユーザーのビューに表示されていない場合は進みません。
environment
environmentオブジェクトには、動作しているAPL環境に関するランタイム情報が含まれます。environmentの値は、APLドキュメントの存続期間中は変更されません。
次の表は、environmentオブジェクトのプロパティの一覧です。設定可否列は、各環境プロパティが、APLドキュメントのenvironmentプロパティを通じてAPLドキュメント内で設定できるかどうかを示します。
| プロパティ | 型 | 設定可否 | 説明 |
|---|---|---|---|
|
|
文字列 |
× |
ランタイム環境の名前です。 |
|
|
文字列 |
× |
ランタイム環境のバージョンです。 |
|
|
ブール値 |
× |
|
|
|
次のいずれか: |
× |
ランタイムのアニメーション特性です。 |
|
|
文字列 |
× |
サポートされているAPLのバージョンです。APLの現在のバージョンは2024.3です。 |
|
|
ブール値 |
× |
|
|
|
ブール値 |
× | |
|
|
ブール値 |
× |
|
|
|
マップ |
× |
リクエストされてサポートされているExtensionです。 |
|
|
数値 |
× |
オペレーティングシステムによってリクエストされた通常のフォントサイズのパーセンテージです。 |
|
|
文字列 |
◯ |
テキスト表示に使用されるデフォルト言語(BCP-47形式)です。 |
|
|
次のいずれか: |
◯ |
ドキュメントのコンポーネントとテキストレイアウトのデフォルトの方向です。 |
|
|
配列 |
× |
このドキュメントによって読み込まれたパッケージの配列です。 |
|
|
次のいずれか: |
× |
ドキュメントの現在のインフレートが初回のインフレートか、後続の再インフレートかを示します。 |
|
|
次のいずれか: |
× |
画面モードの設定です。 |
|
|
ブール値 |
× |
スクリーンリーダーが有効な場合はtrueです。 |
|
|
オブジェクト |
× |
システムの標準のタイミングに関する設定情報です。 |
agentName
ランタイム環境の名前です。この名前はランタイムによって割り当てられる文字列で、デバッグに役立ちます。可能な場合は、APLのバグや問題をレポートするときにこの情報を提供してください。agentNameは、必ずしも特定の形式や構造を持つとは限りません。
値に基づく条件付き応答を提供する目的でこの値を使用しないでください。この値は、エージェントが更新されると変更される可能性があります。
agentVersion
ランタイム環境のバージョンです。これはランタイムによって割り当てられる文字列で、デバッグに役立ちます。可能な場合は、APLのバグや問題をレポートするときにこの情報を提供してください。agentVersionは、必ずしも特定の形式や構造を持つとは限りません。
値に基づく条件付き応答を提供する目的でこの値を使用しないでください。この値は、エージェントが更新されると変更される可能性があります。
allowOpenURL
ブール値です。OpenURLコマンドが有効な場合はtrue、有効でない場合はfalseになります。
animation
デバイスでのアニメーションサポートのレベルを示します。animationの有効な値は次のとおりです。
| 名前 | 説明 |
|---|---|
none |
このデバイスではアニメーションがサポートされていません。すべてのアニメーションコマンドは高速モードで実行されます。 |
slow |
このデバイスはアニメーションをサポートしていますが、パフォーマンスに明らかな制限があります。 |
normal |
このデバイスでは、標準的なアニメーションが妥当な速度で実行されます。 |
この値を常に確認し、environment.animationがslowの場合はアニメーションを簡素化するか削除してください。
aplVersion
このデバイスでサポートされているAPLのバージョンです。この機能はAPLバージョン1.1で追加されました。現在のバージョンのAPLでは、aplVersionプロパティは2024.3を返します。
APL 1.0ではこのプロパティが存在しないため、nullが返されます。
たとえば、APLの現在のバージョンに基づいてアトリビューション文字列を作成するには、次のように記述できます。
{
"resources": [
{
"strings": {
"versionString": "これはAPLバージョン1.0以前です"
},
"colors": {
"versionColor": "red"
}
},
{
"when": "${environment.aplVersion}",
"strings": {
"versionString": "これは想定外のAPLバージョンです:${environment.aplVersion}"
},
"colors": {
"versionColor": "yellow"
}
},
{
"when": "${environment.aplVersion == '2024.3'}",
"strings": {
"versionString": "これは想定されているAPLバージョン2024.3です"
},
"colors": {
"versionColor": "green"
}
}
]
}
1.1以降で導入された機能を使用する場合、ドキュメントの該当するセクションを、aplVersionを確認するwhen句でラップする必要があります。
disallowEditText
このランタイムでEditTextコンポーネントが無効になっている場合はtrueです。EditTextコンポーネントは画面上のスペースを占有しますが、コンポーネントのコンテンツは表示されません。コンポーネントはユーザー操作に応答しません。
disallowDialog
このランタイムでSpeakItemコマンドとSpeakListコマンドが無効になっている場合はtrueです。無効なコマンドは無視されます。
disallowVideo
このランタイムでVideoコンポーネントが無効になっている場合はtrueです。Videoコンポーネントは引き続き画面上のスペースを占有しますが、ビデオは再生されず、コンポーネントはコマンドに応答しません。
extension
extensionプロパティは、リクエストされて読み込まれたExtensionの状態を報告します。これには、名前の文字列とExtensionで定義された値のマップが含まれています。名前の文字列は、APLドキュメントでリクエストされたExtensionの名前です(extensionsを参照してください)。たとえば、ドキュメントで「aplext:remotebutton:v13」というExtensionを「Button」という名前でリクエストした場合、次のデータバインディング式を使用してそのExtensionの有無を確認できます。
"when": "${environment.extension.Button}"
マップはtrueと見なされます。たとえば、Extensionによって環境に「Button」Extensionの情報のマップが提供されたとします。
{
"author": "Fred Flintstone",
"version": "1.3"
}
この場合、ドキュメントに次のように記述できます。
{
"type": "Text",
"when": "${environment.extension.Button}",
"text": "Extensionのバージョン${environment.extension.Button.version}を読み込みました"
}
このテキストコンポーネントは、「Button」というExtensionが存在する場合にのみインフレートされ、読み込まれたExtensionのバージョンが表示されます。
fontScale
オペレーティングシステムのアクセシビリティ設定で指定されている、フォントの相対表示サイズを返します。ほとんどのオペレーティングシステムには、ユーザーが制御できるアクセシビリティ設定があり、視覚に障がいのあるユーザー向けにフォントサイズを標準より大きくすることができます。この数値は、ユーザーがリクエストしたフォントサイズの倍率です。デフォルト設定は1.0です。多くのオペレーティングシステムでは、1.5と2.0のアクセシビリティ倍率もサポートされています。
lang
lang環境プロパティは、デフォルトのランタイム言語を報告します。これにはBCP-47文字列(「en-US」や「ja-JP」など)が含まれています。
langプロパティを使用して、言語に適したリソースを選択できます。
次の例は、指定された言語に応じて変わるアトリビューション文字列リソースを作成する方法を示しています。
リソースの定義
{
"resources": [
{
"strings": {
"helloText": "Hello"
}
},
{
"when": "${environment.lang == 'ja-JP'}",
"strings": {
"helloText": "こんにちは"
}
}
]
}
リソースの使用
{
"type": "Text",
"text": "@helloText"
}
デフォルトのlang値はランタイムソフトウェアによって指定されます。この値は空の文字列になることがあり、その場合は特定の言語設定に一致しません。APLドキュメントのenvironmentプロパティを使用すると、デフォルトのlang値をオーバーライドできます。
ドキュメントレベルのlangプロパティを設定するためのベストプラクティスは、ドキュメントのenvironmentプロパティを使用して、langをデータソースの値にバインドすることです。スキルコードでは、スキルリクエストのロケールに基づいてデータソースにlang値を設定します。
layoutDirection
layoutDirection環境プロパティは、テキストとコンポーネントのデフォルトのレイアウト方向を報告します。layoutDirectionの有効な値は次のとおりです。
| 名前 | 説明 |
|---|---|
|
|
左から右 |
|
|
右から左 |
layoutDirectionがコンポーネントに及ぼす影響の詳細については、layoutDirectionを参照してください。
layoutDirectionプロパティを使用して、方向に応じたリソースを作成できます。
以下の例は、前方矢印を表示するリソースを作成する方法を示しています。左から右のドキュメントの場合、リソースは右を指す矢印のUnicode文字を表示します。右から左のドキュメントの場合、リソースは左を指す矢印のUnicode文字を表示します。
リソースの定義
{
"resources": [
{
"strings": {
"forwardArrow": "→"
}
},
{
"when": "${environment.layoutDirection == 'RTL'}",
"strings": {
"forwardArrow": "←"
}
}
]
}
リソースの使用
{
"type": "Text",
"text": "@forwardArrow"
}
デフォルトのlayoutDirection値はランタイムソフトウェアによって指定されます。APLドキュメントのenvironmentプロパティを使用すると、デフォルトのlang値をオーバーライドできます。
ドキュメントレベルのlayoutDirectionプロパティを設定するためのベストプラクティスは、ドキュメントのenvironmentプロパティを使用して、layoutDirectionをデータソースの値にバインドすることです。スキルロジックでは、スキルリクエストのロケールに基づいてデータソースにlayoutDirection値を設定します。
packages
このドキュメントでimportプロパティから読み込まれたパッケージの配列です。配列の各エントリは、次の表に示すプロパティを持つオブジェクトです。
| プロパティ | 型 | 説明 |
|---|---|---|
|
name |
文字列 |
パッケージの名前 |
|
source |
文字列 |
パッケージのソース |
|
version |
文字列 |
パッケージのバージョン |
配列内のパッケージの順序は未定義です。
ImportPackageによって読み込まれるパッケージは、ドキュメントのインフレート後に読み込まれるため、この配列には含まれません。
reason
reason環境プロパティは、ドキュメントが最初にインフレートされたときはinitialを返し、Reinflateによって再インフレートされた場合はreinflationを返します。ドキュメントのサイズ変更と再インフレートの詳細については、サイズ変更が可能なタブレットなどのデバイスをサポートするを参照してください。
screenMode
色の表示方法に関するアクセシビリティ設定を返します。指定可能な値は、normalとhigh-contrastの2つです。high-contrastがリクエストされた場合、テキストと画像の表示に使用する色として、視覚に障がいのあるユーザーが異なる要素を区別できるような色を選択する必要があります。
screenReader
trueの場合、ユーザーがデバイスのスクリーンリーダーを有効にしたことを示します。
timing
標準のシステムタイミング情報を返します。これらの値は、デバイスの特性やアクセシビリティ設定によって変わります。これらの値は、ドキュメントで絶対数値ではなくタイミング値を設定する場合に使用します。
すべてのタイミング値はミリ秒数で表され、すべての速度値は秒あたりのdpで表されます。以下の例に示した値は参考情報であり、実行時には異なる可能性があります。
| 名前 | 例 | 説明 |
|---|---|---|
|
|
300 |
最初のタップを放してから2回目のタップを開始するまでの最大時間です。この時間以内であればダブルタップと見なされます。 |
|
|
500 |
押下イベントが長押しイベントに変わるまでの最小押下時間です。 |
|
|
50 |
フリックを開始するために必要な最小速度(dp/秒)です。 |
|
|
64 |
プログラムで呼び出されたときに、コンポーネントを「押下」状態として表示する時間の長さです。 |
|
|
100 |
ユーザーがコンポーネントをタップしていたか、領域をスクロール/スワイプしていたかを判断するときに、ユーザーがタッチポイントを動かしたかどうかを確認するために待機する時間です。 |
|
|
500 |
タップジェスチャーと見なされる最大速度(dp/秒)です。 |
localTime
localTimeプロパティは、Unixエポック(1970年1月1日00:00:00 UTC)以降に経過したミリ秒数を、UTCからのローカルタイムゾーンオフセットと夏時間によって調整したものです。localTimeプロパティはutcTimeプロパティから派生します。localTimeプロパティは、夏時間やタイムゾーンの変更など、システム時刻の変更に伴って前後に「ジャンプ」する可能性があります。localTimeをイベント期間の測定に使用しないでください。
utcTime
utcTimeプロパティは、Unixエポック(1970年1月1日00:00:00 UTC)から経過したミリ秒数です。utcTimeプロパティは通常は単調に増加しますが、NTPを使用するデバイスでは、タイムサーバーと定期的に同期するためにわずかにシフトすることがあります。utcTimeプロパティは、実際の経過時間を測定するのに適しています。
データバインディングコンテキストを拡張する
APLレイアウトにはパラメーターが含まれます。レイアウトをインフレートすると、次の例に示すように、データバインディングコンテキストに名前付きのパラメーターが追加されます。
"myQuoteLayout": {
"parameters": [ "quotes" ],
"item": {
"type": "Text",
"text": "${quotes.shakespeareQuotes[0]}"
}
}
// インフレート
{
"type": "myQuoteLayout",
"quotes": {
"shakespeareQuotes": [
"一番大事なことは、おのれに忠実なれ...",
"この婦人は大仰なことばかり言うと私は思う。",
"すべての人を愛し、信頼するのを一握りの人に留めれば、無難に生きれる。"
],
"shakespeareSonnets": [
"くたびれ果てて私は寝床へと急ぐ。旅に疲れた手足を伸ばせるところへと..."
]
}
この例では、quotesはカスタムmyQuoteLayoutのパラメーターです。myQuoteLayoutが使用されるときにデータバインディングコンテキストが拡張され、一致する値を持つ新しいquotesプロパティが追加されます。quotesが指定されていない場合は、quotesのデフォルト値(通常はnull)がデータバインディングコンテキストに追加されます。この追加されたデータバインディングコンテキストは、カスタムレイアウトとその子のインフレートに対してのみ有効です。
データバインディングコンテキストの拡張
コンポーネントがインフレートされると、データバインディングコンテキストが拡張され、インフレートされたコンポーネントに追加情報が渡されます。
コンポーネントバインドの拡張
各コンポーネントには、現在のデータバインディングコンテキストを拡張するオプションのbindプロパティがあります。bindプロパティは、(name, value, type)のタプルの順序付き配列です。各値は現在のデータバインディングコンテキストで評価され、コンテキストに追加されます。
コンポーネントの子要素の拡張
複数の子コンポーネントを持つことができるコンポーネントでは、データバインディングコンテキストに次のグローバル名が追加されます。
| 名前 | 説明 |
|---|---|
| data | コンポーネントのインフレート時に、ユーザー指定のデータ配列から割り当てられる新しいデータです。 |
| index | 現在の子コンポーネントの0から始まるインデックスです。 |
| ordinal | 現在の子コンポーネントの1から始まる順序数です。順序数の付け方については、SequenceコンポーネントとContainerコンポーネントのnumberingを参照してください。 |
| length | 現在のコンポーネントに含まれている子コンポーネントの合計数です。 |
dataとordinalは、コンポーネントに適切なプロパティが設定されている場合に設定されます。
複数子コンポーネントの一覧については、複数子コンポーネントのプロパティを参照してください。
データバインディングコンテキストを明示的に伝播する
親コンポーネントのindex、ordinal、lengthの各プロパティを、子コンポーネントで参照できるようにしたい場合があります。たとえば、Sequenceコンポーネントの子コンポーネントにContainerがあるとします。このContainerにも独自の子コンポーネントがあります。Containerの子のindexプロパティは、SequenceではなくContainerに基づきます。Containerの内部からSequenceのindexにアクセスするには、bindプロパティを使用してindexを明示的に下位に伝播します。
以下の例では、Sequenceの各子コンポーネントとして、FrameコンポーネントとTextコンポーネントを表示するContainerが含まれています。このとき、各行のTextコンポーネントに、Sequenceに基づく項目インデックスを表示しようとしています。
最初の例には問題があります。Textコンポーネント内の${index}という式は、リスト内のどの項目でも1になります。この問題は、Containerが複数子コンポーネントであり、その子コンポーネントに対する独自のindexプロパティを持っているために発生します。つまり、Container内のTextコンポーネントのindexは、Sequenceのリスト項目全体におけるインデックスではなく、Container内でのインデックス(1)を表しています。
次の例は、この問題の解決方法を示しています。この例では、Containerでbindを使用して、parentIndexという変数にindexプロパティを設定しています。Containerコンポーネントの子コンポーネントは、この変数をindexプロパティの代わりに使用します。これで、Sequence内の各項目にSequenceに基づくインデックスが表示されるようになります。
リソースの定義
パッケージに定義されているリソースは、現在のデータバインディングコンテキストに@<名前>というパターンで追加されます。たとえば、前に挙げた例のmyBlueという色は、明示的に${@myBlue}として参照できますが、暗黙的に@myBlueとして参照することもできます。
配列を使用したデータバインディング
多くのAPL式には配列の評価が含まれます。APLは、配列型の強制、暗黙的な配列化、データバインディング式の配列への補間をサポートしています。
配列型の強制
プロパティが既知の型の配列を保持するものとして定義されている場合、配列の各要素には、プロパティの割り当て時にその型が強制されます。たとえば、数値の配列が想定されたレイアウトでは、割り当て時にその配列の各要素に数値が強制されます。
暗黙的な配列化
便宜上、値の配列をとるすべてのAPLプロパティには、配列の角かっこを持たない単一のプロパティを使用することもできます。たとえば、Containerのitemsプロパティはコンポーネントの配列を受け取ります。次のアプローチはどちらも同等になります。
"item": {<<項目>>}
"item": [ {<<項目>>} ]
APLランタイムは、どちらも長さ1の配列に展開します。
配列を想定するプロパティには複数形のエイリアスがあります。したがって、itemとitemsは同じプロパティを表します。
データバインディング式の配列への補間
配列の展開では、配列から配列への補間がサポートされます。次に例を示します。
// コンテキスト
{
"a": "value",
"b": [ "alpha", "bravo" ]
}
"values": "${a}" -> values = [ "value" ] // 暗黙的な配列化
"values": [ "${a}" ] -> values = [ "value" ]
"values": "${b}" -> values = [ "alpha", "bravo" ]
"values": [ "x", "${b}", "${a}" ] -> values = [ "x", "alpha", "bravo", "value" ]
配列化では次のルールが使用されます。
- 値が文字列の場合、データバインディングを使用して値を評価し、正しい型を強制して、配列化を適用します。
- 値が配列の場合、配列の各文字列要素について、データバインディングを使用してその要素を評価します。結果が単一の項目の場合、それを配列に挿入します。値が項目の配列の場合、すべての項目を配列に挿入します。
関連トピック
最終更新日: 2025 年 11 月 04 日