APLデータバインディングの評価


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という数値が語句の一部として挿入されています。次に、colormyBlueに設定されています。これはユーザー定義のリソースを参照します。最後に、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ドキュメントがインフレートされると、データバインディングコンテキストはクリアされます。クリアな状態のデータバインディングコンテキストには、次の定義済みオブジェクトが含まれています。

プロパティ 説明 動的

displayState

画面上でのドキュメントの表示状態です。

elapsedTime

このドキュメントの実行時間(ミリ秒単位)です。

environment

現在のランタイム環境に関する情報です。

×

localTime

ローカル時間(ミリ秒)です。

Array

ビルトインの配列関数です。関数呼び出しを参照してください。

×

Log

ビルトインのログ関数です。関数呼び出しを参照してください。

×

Map

ビルトインのマップ関数です。関数呼び出しを参照してください。

×

Math

ビルトインの数学関数です。関数呼び出しを参照してください。

×

String

ビルトインの文字列関数です。関数呼び出しを参照してください。

×

Time

ビルトインの時間関数です。時間関数を参照してください。

×

utcTime

UTC時間(ミリ秒)です。

viewport

現在のデバイスの設定情報です。データバインディングコンテキストのViewportオブジェクトを参照してください。

×

displayState

画面上のドキュメントの現在の状態を示す値を返します。displayStateは、次の表の値のいずれかになります。

名前 説明

hidden

ドキュメントは画面に表示されていません。ドキュメントはティックイベントを生成せず、不規則な間隔でイベントを生成します。正しい動作をするドキュメントは、この状態に入るとすべてのアニメーションを停止します。

background

ドキュメントは画面上に表示されているか、画面上のほかのコンテンツによって大部分が隠されています。ドキュメントにシステムのメインのフォーカスがない状態です。ドキュメントはティックイベントを生成しますが、ドキュメントアニメーションは最小限に抑える必要があります。

foreground

ドキュメントは画面上で前面に表示されています。

displayStateプロパティは読み取り専用です。

elapsedTime

elapsedTimeプロパティは、このドキュメントが作成されてからミリ秒単位で単調に増加する時間です。ドキュメントがレンダリングされたときに0から開始し、ドキュメントが画面に表示されている間カウントアップします。elapsedTimeプロパティは、ドキュメントが「フリーズ」しているか、ユーザーのビューに表示されていない場合は進みません。

environment

environmentオブジェクトには、動作しているAPL環境に関するランタイム情報が含まれます。environmentの値は、APLドキュメントの存続期間中は変更されません。

次の表は、environmentオブジェクトのプロパティの一覧です。設定可否列は、各環境プロパティが、APLドキュメントのenvironmentプロパティを通じてAPLドキュメント内で設定できるかどうかを示します。

プロパティ 設定可否 説明

agentName

文字列

×

ランタイム環境の名前です。

agentVersion

文字列

×

ランタイム環境のバージョンです。

allowOpenURL

ブール値

×

OpenURLコマンドが有効な場合はtrueです。

animation

次のいずれか:noneslownormal

×

ランタイムのアニメーション特性です。

aplVersion

文字列

×

サポートされているAPLのバージョンです。APLの現在のバージョンは2024.3です。

disallowEditText

ブール値

×

EditTextコンポーネントが無効な場合はtrueです。

disallowDialog

ブール値

×

SpeakItemコマンドとSpeakListコマンドが無効な場合はtrueです。

disallowVideo

ブール値

×

Videoコンポーネントが無効な場合はtrueです。

extension

マップ

×

リクエストされてサポートされているExtensionです。

fontScale

数値

×

オペレーティングシステムによってリクエストされた通常のフォントサイズのパーセンテージです。

lang

文字列

テキスト表示に使用されるデフォルト言語(BCP-47形式)です。

layoutDirection

次のいずれか: LTRRTL

ドキュメントのコンポーネントとテキストレイアウトのデフォルトの方向です。

packages

配列

×

このドキュメントによって読み込まれたパッケージの配列です。

reason

次のいずれか:initialreinflation

×

ドキュメントの現在のインフレートが初回のインフレートか、後続の再インフレートかを示します。

screenMode

次のいずれか:normalhigh-contrast

×

画面モードの設定です。

screenReader

ブール値

×

スクリーンリーダーが有効な場合はtrueです。

timing

オブジェクト

×

システムの標準のタイミングに関する設定情報です。

agentName

ランタイム環境の名前です。この名前はランタイムによって割り当てられる文字列で、デバッグに役立ちます。可能な場合は、APLのバグや問題をレポートするときにこの情報を提供してください。agentNameは、必ずしも特定の形式や構造を持つとは限りません。

値に基づく条件付き応答を提供する目的でこの値を使用しないでください。この値は、エージェントが更新されると変更される可能性があります。

agentVersion

ランタイム環境のバージョンです。これはランタイムによって割り当てられる文字列で、デバッグに役立ちます。可能な場合は、APLのバグや問題をレポートするときにこの情報を提供してください。agentVersionは、必ずしも特定の形式や構造を持つとは限りません。

値に基づく条件付き応答を提供する目的でこの値を使用しないでください。この値は、エージェントが更新されると変更される可能性があります。

allowOpenURL

ブール値です。OpenURLコマンドが有効な場合はtrue、有効でない場合はfalseになります。

animation

デバイスでのアニメーションサポートのレベルを示します。animationの有効な値は次のとおりです。

名前 説明
none このデバイスではアニメーションがサポートされていません。すべてのアニメーションコマンドは高速モードで実行されます。
slow このデバイスはアニメーションをサポートしていますが、パフォーマンスに明らかな制限があります。
normal このデバイスでは、標準的なアニメーションが妥当な速度で実行されます。

この値を常に確認し、environment.animationslowの場合はアニメーションを簡素化するか削除してください。

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の有効な値は次のとおりです。

名前 説明

LTR

左から右

RTL

右から左

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

色の表示方法に関するアクセシビリティ設定を返します。指定可能な値は、normalhigh-contrastの2つです。high-contrastがリクエストされた場合、テキストと画像の表示に使用する色として、視覚に障がいのあるユーザーが異なる要素を区別できるような色を選択する必要があります。

screenReader

trueの場合、ユーザーがデバイスのスクリーンリーダーを有効にしたことを示します。

timing

標準のシステムタイミング情報を返します。これらの値は、デバイスの特性やアクセシビリティ設定によって変わります。これらの値は、ドキュメントで絶対数値ではなくタイミング値を設定する場合に使用します。

すべてのタイミング値はミリ秒数で表され、すべての速度値は秒あたりのdpで表されます。以下の例に示した値は参考情報であり、実行時には異なる可能性があります。

名前 説明

doublePressTimeout

300

最初のタップを放してから2回目のタップを開始するまでの最大時間です。この時間以内であればダブルタップと見なされます。

longPressTimeout

500

押下イベントが長押しイベントに変わるまでの最小押下時間です。

minimumFlingVelocity

50

フリックを開始するために必要な最小速度(dp/秒)です。

pressedDuration

64

プログラムで呼び出されたときに、コンポーネントを「押下」状態として表示する時間の長さです。

tapOrScrollTimeout

100

ユーザーがコンポーネントをタップしていたか、領域をスクロール/スワイプしていたかを判断するときに、ユーザーがタッチポイントを動かしたかどうかを確認するために待機する時間です。

maximumTapVelocity

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 現在のコンポーネントに含まれている子コンポーネントの合計数です。

dataordinalは、コンポーネントに適切なプロパティが設定されている場合に設定されます。

複数子コンポーネントの一覧については、複数子コンポーネントのプロパティを参照してください。

データバインディングコンテキストを明示的に伝播する

親コンポーネントのindexordinallengthの各プロパティを、子コンポーネントで参照できるようにしたい場合があります。たとえば、Sequenceコンポーネントの子コンポーネントにContainerがあるとします。このContainerにも独自の子コンポーネントがあります。Containerの子のindexプロパティは、SequenceではなくContainerに基づきます。Containerの内部からSequenceindexにアクセスするには、bindプロパティを使用してindexを明示的に下位に伝播します。

以下の例では、Sequenceの各子コンポーネントとして、FrameコンポーネントとTextコンポーネントを表示するContainerが含まれています。このとき、各行のTextコンポーネントに、Sequenceに基づく項目インデックスを表示しようとしています。

最初の例には問題があります。Textコンポーネント内の${index}という式は、リスト内のどの項目でも1になります。この問題は、Containerが複数子コンポーネントであり、その子コンポーネントに対する独自のindexプロパティを持っているために発生します。つまり、Container内のTextコンポーネントのindexは、Sequenceのリスト項目全体におけるインデックスではなく、Container内でのインデックス(1)を表しています。


次の例は、この問題の解決方法を示しています。この例では、Containerbindを使用して、parentIndexという変数にindexプロパティを設定しています。Containerコンポーネントの子コンポーネントは、この変数をindexプロパティの代わりに使用します。これで、Sequence内の各項目にSequenceに基づくインデックスが表示されるようになります。


リソースの定義

パッケージに定義されているリソースは、現在のデータバインディングコンテキストに@<名前>というパターンで追加されます。たとえば、前に挙げた例のmyBlueという色は、明示的に${@myBlue}として参照できますが、暗黙的に@myBlueとして参照することもできます。

配列を使用したデータバインディング

多くのAPL式には配列の評価が含まれます。APLは、配列型の強制、暗黙的な配列化、データバインディング式の配列への補間をサポートしています。

配列型の強制

プロパティが既知の型の配列を保持するものとして定義されている場合、配列の各要素には、プロパティの割り当て時にその型が強制されます。たとえば、数値の配列が想定されたレイアウトでは、割り当て時にその配列の各要素に数値が強制されます。

暗黙的な配列化

便宜上、値の配列をとるすべてのAPLプロパティには、配列の角かっこを持たない単一のプロパティを使用することもできます。たとえば、Containeritemsプロパティはコンポーネントの配列を受け取ります。次のアプローチはどちらも同等になります。

"item": {<<項目>>}
"item": [ {<<項目>>} ]

APLランタイムは、どちらも長さ1の配列に展開します。

配列を想定するプロパティには複数形のエイリアスがあります。したがって、itemitemsは同じプロパティを表します。

データバインディング式の配列への補間

配列の展開では、配列から配列への補間がサポートされます。次に例を示します。

// コンテキスト
{
	"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 日