APLデータバインディング構文
Alexa Presentation Language(APL)ドキュメントが表示されるときにAlexaによって評価される式を記述するには、データバインディング構文を使用します。データバインディング式を使用すると、コンポーネントプロパティをデータソースにバインドしたり、Viewportの特性などの条件に応じてコンポーネントを表示または非表示にする条件付きロジックを作成したりできます。
データバインディング式について
データバインディング式は、JSON文字列内で使用します。データバインディング式の形式は「${expression}」です。"${2}+${2} = ${2+2}"のように、任意の数の式を文字列内に記述できます。
式は現在のデータバインディングコンテキスト内で評価されます。データバインディングコンテキストは、ブール値、数値、文字列、配列、オブジェクト、null値、定義済みのリソースへの参照をサポートするグローバルディクショナリーです。
サポートされる値のタイプ
識別子
識別子は、データバインディング変数を識別するために使用される名前です。識別子は、C識別子の命名規則である[a-zA-Z_][a-zA-Z0-9_]*に従う必要があります。つまり、識別子は大文字または小文字のASCII英文字かアンダースコアで始まり、その後に0文字以上のASCII英文字、数字、アンダースコアを続けます。
${data}
${_myWord23}
${__AnUgly26_letter__examplE}
文字列リテラル
文字列は、一重引用符または二重引用符を使用して定義します。開始と終了の引用符はセットで使用する必要があります。引用符、キャリッジリターン、改行はエスケープ文字で表します。
${"二重引用符で囲まれた文字列"}
${'一重引用符で囲まれた文字列'}
${"内部の引用符:\"または'"}
式は文字列の中に入れ子にすることもできます。
${"2たす2は${2+2}"}
数値
正の数、負の数、浮動小数点数がサポートされます。指数表記には対応していません。すべての数値は、内部では倍精度浮動小数点数として格納されます。
${1}
${-34.75}
${64000000000}
ブール値
trueとfalseのブール値がサポートされます。
${true}
${false}
null
null定数がサポートされます。
${null}
配列
角かっこ内にカンマ区切りの式のリストを指定することで、データバインディング式の中で配列を定義できます。
${["A", "B", "C"].length} // 3に評価
${["on","off"][0]} // "on"に評価
${[true,"true",1][0]} // ブール値のtrueに評価
マップ
中かっこ内に文字列キーと値のペアを指定することで、データバインディング式の中でマップオブジェクトを定義できます。
${{"A":1, "B":2}["A"]} // 1に評価
リソース
定義済みのリソースをデータバインディングコンテキストで参照するには、予約文字@を使用します。次に例を示します。
${@myBlue}
${@isLandscape ? @myWideValue : @myNarrowValue}
データバインディングに公開するリソースは、APLパッケージで定義します。
絶対ディメンション
ディメンションサフィックスは、数値を絶対Viewportディメンションに変換します。有効なディメンションサフィックスは、dp、px、vh、vwです。
${23 dp} // 23ディスプレイ非依存ピクセル
${10 px} // 10ピクセル
${50 vw} // Viewportの幅の50%
${100vh} // Viewportの高さの100%
ディメンションサフィックスは数値に続ける必要があり、複雑な式には使用できません。たとえば、${(20*20) dp}は有効ではありませんが、${20*20dp}は有効です。
Truthyと強制
データバインディング式では、さまざまなデータ型が使用されます。これらの型はほかの型に変換できます。次の表は、さまざまな変換の例を示しています。この表の例では、Viewportの幅が512dp、DPIが320であると想定しています。
| オブジェクト | 例 | ブール値 | 数値 | 文字列 | 色 | ディメンション |
|---|---|---|---|---|---|---|
| Null | null |
false | 0 | "" | transparent | 0dp |
| ブール値 | true |
true | 1 | "true" | transparent | 0dp |
| ブール値 | false |
false | 0 | "false" | transparent | 0dp |
| 数値 | 23 |
true | 23 | "23" | #00000017 | 23dp |
| 数値 | 0 |
false | 0 | "0" | transparent | 0dp |
| 文字列 | "私の犬" |
true | 0 | "私の犬" | transparent | 0dp |
| 文字列 | "" |
false | 0 | "" | transparent | 0dp |
| 文字列 | "-2.3" |
true | -2.3 |
"-2.3" | transparent | -2.3dp |
| 文字列 | "red" |
true | 0 | "red" | #ff0000ff | 0dp |
| 文字列 | "50vw" |
true | 50 | "50vw" | transparent | 256dp |
| 配列 | [] |
true | 0 | "" | transparent | 0dp |
| マップ | {} |
true | 0 | "" | transparent | 0dp |
| 色 | red |
true | 0 | "#ff0000ff" | #ff0000ff | 0dp |
| ディメンション | 32px |
true | 16 | "16dp" | transparent | 16dp |
| ディメンション | 0vh |
false | 0 | "0dp" | transparent | 0dp |
| ディメンション | 23% |
true | 0.23 | "23%" | transparent | 23% |
| ディメンション | 0% |
false | 0 | "0%" | transparent | 0% |
| ディメンション | auto |
true | 0 | "auto" | transparent | auto |
| その他 | ... |
true | 0 | "" | transparent | 0dp |
ブール型の強制
truthy値とは、真偽を判定するコンテキストで評価したときにtrueと見なされる値です。false、0、""、絶対ディメンションまたは相対ディメンションの0、nullを除いて、すべての値はtruthyです。
数値の強制
ブール型のtrue値は数値の1に変換されます。文字列値はC++のstd::stodメソッドを使用して変換され、ロケールの影響を受けます。絶対ディメンションはディスプレイに依存しないピクセル数に変換されます。相対ディメンションは割合の値に変換されます(たとえば、32%は0.32に変換されます)。それ以外の場合はすべて0に変換されます。
文字列の強制
内部の型は、次の表に示すルールに従って文字列に変換されます。
| オブジェクト | 例 | 結果 | 説明 |
|---|---|---|---|
| Null | null |
'' |
null値は表示されません。 |
| ブール値 | true |
'true' |
ブール値のtrueとfalseは文字列として表示されます。 |
false |
'false' |
||
| 数値 | -23 |
'-23' |
整数では、小数点以下の桁は表示されません。 |
1/3 |
'0.333333' |
非整数では、小数点以下の桁が表示されます。 | |
| 文字列 | "私の\"犬\" " |
'私の"犬" ' |
文字列値です。 |
| 配列 | [...] |
'' |
配列は表示されません。 |
| マップ | {...} |
'' |
マップは表示されません。 |
| 色 | red |
'#ff0000ff' |
色は#rrggbbaaの形式で表示されます。 |
| ディメンション | 23 dp |
'20dp' |
絶対ディメンションは、サフィックスdpを付けて表示されます。 |
| ディメンション | 20 % |
'20%' |
パーセントディメンションは、サフィックス%を付けて表示されます。 |
| ディメンション | auto |
'auto' |
自動ディメンションは「auto」として表示されます。 |
| その他 | ${Math.min} |
'' |
数学関数は表示されません。 |
整数以外の数値に対する固有の形式は定義されていませんが、C++標準のsprintf(buf, "%f", value)に従います。この形式は、ロケールに応じて変わる可能性があります。
色の強制
色の値は、内部的に32ビットのRGBA値として格納されます。数値は32ビットの符号なし整数として扱われ、直接変換されます。文字列値は、色のデータ型の規則に従って解析されます。
絶対ディメンションの強制
数値はdp単位の測定値であると見なされ、絶対ディメンションに変換されます。文字列値は、ディメンションのデータ型の規則に従って解析されます。その他のすべての値は0になります。
相対ディメンションの強制
数値は割合と見なされ、直接変換されます。たとえば、0.5は50%に変換されます。文字列は、ディメンションのデータ型の規則に従って解析されます。その他のすべての値は0になります。
演算子
APLでは、算術演算子、論理演算子、比較演算子、三項演算子がサポートされています。
算術演算子
APLでは、加算、減算、乗算、除算、剰余の標準的な算術演算子がサポートされています。
${1+2} // 3
${1-2} // -1
${1*2} // 2
${1/2} // 0.5
${1%2} // 1
加算と減算は、数値のペア、絶対ディメンション、相対ディメンションに対して機能します。数値が絶対ディメンションまたは相対ディメンションのいずれかと組み合わされると、その数値は適切なディメンションに強制変換されます。
加算演算子は、左オペランドか右オペランドが文字列の場合、文字列を連結する演算子としても使用できます。
${27+''} // '27'
${1+' dog'} // '1 dog'
${'have '+3} // 'have 3'
乗算演算子、除算演算子、剰余演算子は、数値のペアに対して機能します。乗算は、一方のオペランドが相対ディメンションまたは絶対ディメンションで、もう一方のオペランドが数値の場合にも機能します。この計算結果はディメンションになります。除算は、第1オペランドが相対ディメンションまたは絶対ディメンションで、第2オペランドが数値の場合にも機能します。この計算結果はディメンションになります。
剰余演算子はJavaScriptと同じように機能します。
${10 % 3} // 1
${-1 % 2} // -1
${3 % -6} // 3
${6.5 % 2} // 0.5
論理演算子
APLでは、標準的なAND、OR、NOTの論理演算子がサポートされています。
${true || false} // true
${true && false} // false
${!true} // false
&&は、第1オペランドがtrueと見なされない場合は第1オペランドを返し、そうでない場合は第2オペランドを返します。||演算子は、第1オペランドがtrueと見なされる場合は第1オペランドを返し、そうでない場合は第2オペランドを返します。
${7 && 2} // 2
${null && 3} // null
${7 || 2} // 7
${0 || -16} // -16
比較演算子
比較演算子はブール値を返します。
${1 < 2}
${75 <= 100}
${3 > -1}
${4 >= 4}
${myNullValue == null}
${(2>1) == true}
${1 != 2}
比較演算子は、配列やオブジェクトには適用されません。
比較演算子では、型の強制は行われません。たとえば、${1=='1'}という式はfalseを返します。次の表は、有効な比較の一覧です。その他の比較はすべてfalseを返します。
| 比較の種類 | <、>、<=、>= | ==、!= | 備考 |
|---|---|---|---|
|
数値から数値 |
有効 |
有効 | |
|
数値から絶対ディメンション |
有効 |
有効 |
数値はディスプレイに依存しないピクセルディメンションとして扱われます。 |
|
数値から相対ディメンション |
有効 |
有効 |
数値はパーセンテージとして扱われます。たとえば、0.4は40%と等値です。 |
|
相対ディメンションから相対ディメンション |
有効 |
有効 |
ディメンションはパーセンテージとして比較されます。 |
|
絶対ディメンションから絶対ディメンション |
有効 |
有効 |
ディメンションはディスプレイに依存しないピクセル数に変換されます。 |
|
文字列から文字列 |
有効 |
有効 | |
|
ブール値からブール値 |
false |
有効 | |
|
色から色 |
false |
有効 | |
|
NullからNull |
false |
有効 |
|
|
自動ディメンションから自動ディメンション |
false |
有効 |
2つの自動ディメンションは、最終的なサイズが等しくなくても等値になります。 |
|
その他のすべての組み合わせ |
false |
false |
APLの==演算子は、JavaScriptの===演算子に似ています。
Null合体
??演算子はnull合体演算子です。左オペランドがnullでない場合はそのオペランドを返し、それ以外の場合は右オペランドを返します。null合体演算子は連鎖させることができます。
${person.name ?? person.surname ?? 'Hey, you!'}
null合体演算子は、左オペランドがnull以外であればそのオペランドを返します。
${1==2 ?? 'Dog'} // returns false
${1==2 || 'Dog'} // 「Dog」が返される
三項演算子
三項条件演算子${a ? b : c}は左オペランドを評価します。trueまたはtruthy値に評価された場合は、中央のオペランドを返します。そうでない場合は、右オペランドを返します。
${person.rank > 8 ? 'General' : 'Private'}
配列とオブジェクトへのアクセス
配列
配列へのアクセスには[]演算子を使用します。この場合、オペランドは整数でなければなりません。配列は、配列の長さを返す.length演算子もサポートしています。配列の範囲外の要素にアクセスすると、nullが返されます。
${myArray[4]} // 配列の5番目の要素(0から始まるインデックス)
${myArray.length} // 配列の長さ
${myArray[-1])} // 配列の最後の要素
${myArray[myArray.length]} // nullが返される(範囲外)
負のインデックスを渡すと、配列を後ろから数えます。
${a[-1] == a[a.length - 1]} // true
オブジェクト
オブジェクトでは、.(ドット)演算子と[]配列アクセス演算子での文字列値の使用がサポートされます。
${myObject.name} // myObjectの「name」プロパティ
${myObject['name']} // myObjectの「name」プロパティ
プロパティが定義されていない場合、式はnullを返します。
nullに対して.(ドット)演算子または[]演算子を呼び出すと、nullが返されます。
${myNullObject.address.zipcode} // nullが返される
ドット演算子の右オペランドは、有効な識別子でなければなりません。
関数呼び出し
データバインディングでは、いくつのビルトイン関数がサポートされています。関数の形式は次のとおりです。
functionName( arg1, arg2, … )
関数の引数は必須ではありません。関数は単一の値を返します。さまざまな関数式の例を以下に示します。
${Math.floor(1.1)} // 1
${Math.ceil(1.2)} // 2
${Math.round(1.2)} // 1
${Math.min(1,2,3,4)} // 1
${Math.max(1,2,3,4)} // 4
${String.toUpperCase('Hello')} // HELLO
${String.toLowerCase('Hello')} // hello
${String.slice('Hello', 1, -1)} // ell
使用可能な関数は、トップレベルのプロパティによってグループ化されています。
配列関数(Array)
トップレベルのArrayプロパティは、配列を操作するための関数と定数のコレクションです。
以下の例の列では、サンプルの配列としてa = [101,102,103,104,105,106]が使用されています。
| 関数 | 説明 | 例 |
|---|---|---|
Array.indexOf(x,y) |
配列xの要素yのインデックスを返します。配列xにyが含まれない場合は、-1を返します。 |
${Array.indexOf(a,102)} == 1 |
Array.range(start, end, [step]) |
|
|
Array.slice(array,start[,end]) |
インデックス
|
${Array.slice(a,3)} == [104,105,106]${Array.slice(a,1,3)} == [102,103]${Array.slice(a,-2)} == [105,106] |
ログ関数(Log)
トップレベルのLogプロパティは、Logコマンドから出力されるログメッセージを処理するための便利なメソッドを提供します。
| 関数 | 説明 | 例 |
|---|---|---|
|
|
ログレベルの名前を返します。 |
|
|
|
ログレベルの値を返します。 |
|
Logコマンドで説明されている各レベルに相当する数値として、以下の定数が用意されています。これらは数値の昇順に並んでいます。
Log.DEBUGLog.INFOLog.WARNLog.ERRORLog.CRITICAL
各定数の具体的な値は変更される可能性があります。そのため、値は直接使用しないでください。これらの定数間の関係は信頼でき、 常にLog.DEBUG < Log.INFO < Log.WARN < Log.ERROR < Log.CRITICALとなります。
マップ関数(Map)
トップレベルのMapプロパティは、マップを操作するための関数のコレクションです。
次の表に示す例では、xはマップ{'a': 'alpha', 'b': 'bravo'}を想定しています。
| 関数 | 説明 | 例 |
|---|---|---|
|
|
マップxのキーの配列を返します。 |
|
マップ以外に対してMap.keys(x)を呼び出すと、空の配列が返されます。空でない配列に対してMap.keys(x)を呼び出したときに返されるキーの順序は未定義です。
次の例には、文字から単語へのマップを表すmapDataというデータソースが含まれています。ドキュメントはSequenceを表示し、Map.keys関数を使用して、マップ内のすべてのキーの配列をdataプロパティに割り当てます。Sequenceでは、${data}という式でキーにアクセスし、${mapData[data]}という式で値にアクセスできます。
数学関数(Math)
トップレベルのMathプロパティは、数値を計算するための関数と定数のコレクションです。
| 関数 | 説明 | 例 |
|---|---|---|
|
|
xの絶対値を返します。 |
|
|
|
xのアークコサインを返します。 |
|
|
|
xの双曲線アークコサインを返します。 |
|
|
|
xのアークサインを返します。 |
|
|
|
xの双曲線アークサインを返します。 |
|
|
|
xのアークタンジェントを返します。 |
|
|
|
xの双曲線アークタンジェントを返します。 |
|
|
|
y/xのアークタンジェントを返します。 |
|
|
|
xの立法根を返します。 |
|
|
|
x以上の最小の整数を返します。 |
|
|
|
y<xの場合はx、y>zの場合はz、それ以外の場合はyを返します。 |
|
|
|
xのコサインを返します。 |
|
|
|
xの双曲線コサインを返します。 |
|
|
|
eのx乗を返します。eはオイラー定数です。 |
|
|
|
2のx乗を返します。 |
|
|
|
eのx乗マイナス1を返します。 |
|
|
|
xを浮動小数点数に変換します。末尾に「%」文字を付けた場合はパーセンテージを表します。 |
|
|
|
x以下の最大の整数を返します。 |
|
|
|
引数の2乗の和の平方根を返します。 |
|
|
|
xを整数に変換します。bは文字列変換に使用するオプションの基数です。0で自動検出するか、2~36で基数を定義します。 |
|
|
|
xが有限の場合はtrueを返します。xが無限または非数(NaN)の場合はfalseを返します。 |
|
|
|
xが無限の場合はtrueを返します。 |
|
|
|
xが非数(NaN)の場合は |
|
|
|
xの自然対数を返します。 |
|
|
|
1+xの自然対数を返します。 |
|
|
|
xの底を10とする対数を返します。 |
|
|
|
xの底を2とする対数を返します。 |
|
|
|
最大の引数を返します。 |
|
|
|
最小の引数を返します。 |
|
|
|
xのy乗を返します。 |
|
|
|
0と1の間の乱数を返します。 |
|
|
|
xに最も近い整数を返します。 |
|
|
|
xの符号を返します。 |
|
|
|
xのサインを返します。 |
|
|
|
xの双曲線サインを返します。 |
|
|
|
xの平方根を返します。 |
|
|
|
xのタンジェントを返します。 |
|
|
|
xの双曲線タンジェントを返します。 |
|
|
|
xの整数部を返します。 |
|
| 定数 | 説明 | 値 |
|---|---|---|
Math.E |
オイラーの定数(e) | 2.718281828459045 |
Math.LN2 |
2の自然対数 | 0.6931471805599453 |
Math.LN10 |
10の自然対数 | 2.302585092994046 |
Math.LOG2E |
eの底を2とする対数 | 1.4426950408889634 |
Math.LOG10E |
eの底を10とする対数 | 0.4342944819032518 |
Math.PI |
円周率(π) | 3.141592653589793 |
Math.SQRT1_2 |
0.5の平方根 | 0.7071067811865476 |
Math.SQRT2 |
2の平方根 | 1.4142135623730951 |
文字列関数(String)
トップレベルのStringプロパティは、文字列を操作するための関数のコレクションです。
| 関数 | 説明 | 例 |
|---|---|---|
|
|
文字列 |
|
|
|
文字列 |
|
|
|
文字列 |
|
|
|
文字列 |
|
|
|
文字列の長さを返します。 |
|
|
|
インデックス |
|
|
|
文字列を小文字にします。 |
|
|
|
文字列を大文字にします。 |
|
文字列のlength関数とslice関数は、バイトではなくUnicodeコードポイントで動作します。
以下は、いくつかのString関数の例を示しています。この例では遅延評価も使用されます。データソースには、関数の例が、#{...}プレースホルダーを持つデータバインディング式として格納されています。これにより、ドキュメントは関数のテキストを表示した後、eval()を使用して関数を評価し、その結果を表示できます。
時間関数(Time)
トップレベルのTimeプロパティは、ミリ秒単位の時間値から年、月、日、時、分、秒に変換する関数のコレクションです。この表の例では、バインドされた時間値がT=1567786974710であると想定しています。人間が判読できる表記にすると、2019年9月6日金曜日の16:22:54と710ミリ秒です。
| 関数 | 説明 | 例 |
|---|---|---|
Time.year(x) |
年を返します。 | ${Time.year(T)} == 2019 |
Time.month(x) |
月(0~11)を返します。 | ${Time.month(T)} == 8(9月) |
Time.date(x) |
月内の日付(1~31)を返します。 | ${Time.date(T)} == 6 |
Time.weekDay(x) |
週内の曜日(0~6)を返します。 | ${Time.weekDay(T)} == 5(金曜日) |
Time.hours(x) |
1日のうちの時間(0~23)を返します。 | ${Time.hours(T)} == 16 |
Time.minutes(x) |
1時間のうちの分(0~59)を返します。 | ${Time.minutes(T)} == 22 |
Time.seconds(x) |
1分のうちの秒(0~59)を返します。 | ${Time.seconds(T)} == 54 |
Time.milliseconds(x) |
ミリ秒(0~999)を返します。 | ${Time.milliseconds(T)} == 710 |
Time.format(f, x) |
書式設定されたテキスト文字列を返します。 | ${Time.format('H:mm', T)} == "16:22" |
基本的なデジタル時計を作成するには、TextコンポーネントとlocalTimeプロパティを使用して時間関数を呼び出し、24時間形式の時刻を表示します。
{
"type": "Text",
"bind": {
"name": "T",
"value": "${localTime}"
},
"text": "${Time.hours(T)}:${Time.minutes(T)}"
}
この例では、テキストの式を短縮するためにlocalTimeの値をローカル変数Tにバインドしています。この時計は、午後4時04分のような時刻を16:4としてレンダリングしますが、これは期待した形式ではない可能性があります。条件文を使用して時刻を確認すると、必要に応じて先頭や末尾に0を含めることができます。
次の例に示すように、条件文を使用して12時間時計を表示することもできます。これは時間と分の両方をローカル変数にバインドし、条件文を使用して、12時間形式の時刻にamまたはpmを付けて出力します。
{
"type": "Text",
"bind": [
{
"name": "h",
"value": "${Time.hours(localTime)}"
},
{
"name": "m",
"value": "${Time.minutes(localTime)}"
}
],
"text": "${h >= 12 ? h - 12 : h}:${m < 10 ? '0' : ''}${m} ${h >= 12 ? 'pm' : 'am'}"
}
Time.format関数を使用してコードを単純化することもできます。次の例では、時間に基づく条件文を使用して、最後に「am」または「pm」を追加します。
{
"type": "Text",
"bind": [
{
"name": "h",
"value": "${Time.hours(localTime)}"
}
],
"text": "${Time.format('h:mm', localTime) + (h >= 12 ? ' pm' : ' am')}"
}
Time.format
format関数は、書式コードと時刻値を含む文字列引数を受け取ります。次の書式コードがサポートされています。
| 値 | 範囲 | 説明 |
|---|---|---|
YY |
00~99 | 2桁の年 |
YYYY |
1970~XXXX | 4桁の年 |
M |
1~12 | 月(1=1月) |
MM |
01~12 | 2桁の月(1=1月) |
D |
1~31 | 月内の日付 |
DD |
01~31 | 月内の2桁の日付 |
DDD |
0~N | エポックからの日数(桁数不定) |
H |
0~23 | 24時間表記の時間 |
HH |
00~23 | 24時間表記の2桁の時間 |
HHH |
0~N | エポックからの時間数(桁数不定) |
h |
1~12 | 12時間表記の時間 |
hh |
01~12 | 12時間表記の2桁の時間 |
m |
0~59 | 分 |
mm |
00~59 | 2桁の分 |
mmm |
0~N | エポックからの分数(桁数不定) |
s |
0~59 | 秒 |
ss |
00~59 | 2桁の秒 |
sss |
0~N | エポックからの秒数(桁数不定) |
S |
0~9 | デシ秒 |
SS |
00~99 | センチ秒 |
SSS |
000~999 | ミリ秒 |
すべての書式コードは数字のみを返します。
次の表は、2019年9月6日16:22:54と710ミリ秒という時間値を使用した場合の書式設定関数の例を示しています。
| 書式 | 値 |
|---|---|
DD-MM-YYYY |
06-09-2019 |
M/D/YY |
9/6/19 |
DDD日 |
18145日(エポック以降) |
H:mm |
16:22 |
hh:mm |
04:22 |
H:mm:ss |
16:22:54 |
時刻の書式は、タイマーからの相対時間にも適用できます。次の表は、7523194という値を使用した場合の例を示しています。この値は2時間5分23.194秒に相当します。
| 書式 | 値 |
|---|---|
mmm:ss.S |
125:23.1 |
HHH:mm:ss.SS |
2:05:23.19 |
sss.SSS |
7523.194 |
次の例では、elapsedTimeを使用してドキュメントが読み込まれてからの経過時間を表示します。サンドボックス内のタイマーを再起動するには、ページを更新してください。
データバインディングの文字列の変換
APLはJSONでシリアル化されているため、すべてのデータバインド式はJSON文字列内で定義されます。
{
"MY_EXPRESSION": "${....}"
}
引用符とデータバインディング式の間にスペースがない場合、式の結果はデータバインディング評価の結果になります。次に例を示します。
"${true}" -> ブール値のtrue
"${2+4}" -> 数値6
"${0 <= 1 && 'three'}" -> 文字列「three」
文字列内のデータバインディング式の外側にスペースがある場合、または2つのデータバインディング式が並んでいる場合、結果は連結された文字列になります。
" ${true}" -> 文字列「 true」
"${2+4} " -> 文字列「6 」
"${2+1}${1+2}" -> 文字列「33」
遅延評価
APLでプロパティやバインド変数が評価されるときには、${...}構文で記述された式が評価され、解決されます。場合によっては、この評価を遅延させて、式を解決するタイミングを制御できると便利です。APLバージョン2023.2以降では、#{...}プレースホルダーとeval()ビルトイン関数を使用して、式の評価を遅延させることができます。eval()は、データソース内の式など、自動的には評価されない式を評価するためにも使用できます。
versionプロパティを「2023.2」以降にする必要があります。それより前のversionが設定されたドキュメントでは、サポートされているバージョンのデバイスで実行された場合でも、新しい構文は無視されます。遅延プレースホルダー構文
データバインディングの評価により、#{...}プレースホルダーは標準のデータバインディング式に置き換えられます。ただし、その式の評価は実行されません。つまり、${...}構文が残ります。次の例は、textプロパティで#{...}構文を使用するTextコンポーネントを示しています。
{
"type": "Text",
"text": "式#{1+2}は${1+2}に評価されます"
}
この文字列の通常の評価結果は、"式${1+2}は3に評価されます"という文字列になります。${1+2}という式は文字列内に残ります。
#{...}プレースホルダー内の文字列は有効なAPL式である必要があり、そうでない場合は置換に失敗します。以下は、2つの項目を持つbind配列の例です。変数Xは${1+a}に解決されます。変数Yは、1+が有効な式でないため、評価に失敗します。その結果、Yには#{1+}が含まれたままになります。
"bind": [
{
"name": "X",
"value": "#{1+a}"
},
{
"name": "Y",
"value": "#{1+}"
}
]
eval()関数
eval()ビルトイン関数は、引数を1つ受け取り、その引数に対してデータバインディングアルゴリズムを実行します。引数は、#{...}プレースホルダーで作成された文字列か、データソースで提供された文字列です。
次の例は、3つのbind項目を示しています。Formatは遅延データバインディング構文を使用し、Greetingはeval()関数を呼び出します。
"bind": [
{
"name": "Format",
"value": "こんにちは、#{Name}さん"
},
{
"name": "Name",
"value": "クリス"
},
{
"name": "Greeting",
"value": "${eval(Format)}"
}
]
バインディングは次の値に解決されます。
Format = "こんにちは、${Name}さん"
Name = "クリス"
Greeting = "こんにちは、クリスさん"
次の例に示すように、eval()呼び出しは入れ子にすることもできます。
"bind": [
{
"name": "A",
"value": "#{B}"
},
{
"name": "B",
"value": "#{C}"
},
{
"name": "C",
"value": "こんにちは"
},
{
"name": "D",
"value": "${eval(A)}"
},
{
"name": "E",
"value": "${eval(eval(A))}"
}
]
この例のバインディングは次の値に解決されます。
A = "${B}"
B = "${C}"
C = "こんにちは"
D = "${C}"
E = "こんにちは"
eval(A)を呼び出した結果は、"こんにちは"ではなく"${C}"になることに注意してください。
リソースのローカライゼーションに遅延評価を使用する
遅延評価を使用すると、resourcesとして定義される項目に動的なデータを埋め込むことができます。この手法は、言語固有の文字列を書式設定する場合に便利です。
次の例では、異なるロケールに応じて異なる書式を使用するTEMPERATURE_FORMATリソースを定義します。データソースのロケールを変更して、画面が更新されることを確認してください。
この例では、言語に応じて温度を地域に適した形式に変換します。en-US環境では、APLはリソースを次の値に設定します。
CELSIUS = "${TEMP} °C"
FAHRENHEIT = "${TEMP * 9 / 5 + 32} °F"
TEMPERATURE_FORMAT = "The temperature is ${TEMP * 9 / + 32} °F" // 「en-US」の句を選択
text = "The temperature is 77 °F"
textプロパティのeval()呼び出しにより、TEMP=25.0を使用してTEMPERATURE_FORMAT文字列が評価され、"The temperature is 77 °F"という結果に変換されます。SetValueなどによってTEMPの値を変更すると、textプロパティで式が再評価され、コンポーネントが更新されます。
遅延評価とデータソース
eval()関数を使用すると、データソースでドキュメントに渡されたデータバインディング式を評価することもできます。
デフォルトでは、データバインディングの評価はデータソース内の式を処理しません。たとえば、データソースのプロパティを${1+2}に設定し、そのデータソースのプロパティをドキュメント内のコンポーネントにバインドしたとします。このコンポーネントがインフレートされたとき、コンポーネントのプロパティには、評価結果の"3"ではなく"${1+2}"というテキストが含まれます。
データソースのプロパティ内のデータバインディング式を処理するには、プロパティをeval()関数に渡します。
次の例は、データソースでeval()関数を使用する方法を示しています。
eval()による配列とオブジェクトの処理
配列またはオブジェクトに対してeval()関数を呼び出すと、配列の各エントリやオブジェクトの各プロパティが個々に評価されます。この機能は、一連の書式文字列を処理する場合に役立ちます。
たとえば、2つのプロパティを持つオブジェクトXがあり、それらのプロパティにデータバインディング式が含まれているとします。
X = {
"formal_greeting": "${NAME}様、お世話になっております",
"casual_greeting": "${NAME}さん、こんにちは"
}
NAME = "ラージ"
Xをeval()に渡すと、各プロパティが解決されたオブジェクトが返されます。
eval(X) = {
"formal_greeting": "ラージ様、お世話になっております",
"casual_greeting": "ラージさん、こんにちは"
}
次の例は、オブジェクトに対してeval()を呼び出すAPLドキュメントを示しています。
遅延評価のガイドライン
eval()関数はコストが高い
eval()関数では、関数呼び出しのたびに式が解析され、評価されます。つまり、eval()関数はコストが高い操作です。eval()を使用する前に、別のアプローチを使用できないかどうかを検討してください。
eval()の再起呼び出しは避ける
終了しないeval()の再起呼び出しを作成しないように注意してください。
次の例では、自身に対してeval()を呼び出すbind変数Aが作成されます。
再帰呼び出しの例
{
"type": "Text",
"bind": {
"name": "A",
"value": "ハッ#{eval(A)}"
},
"text": "私は無敵だ!${eval(A)}!"
}
APLでは、再帰的な評価の呼び出しの深さが制限されています。そのため、この例では、無限に長い文字列が作成される代わりに、「私は無敵だ! ハッ ハッ ハッ${eval(A)}!」のようなテキストが表示される可能性があります。上限は3以上であることが保証されていますが、特定のランタイムではそれよりも大きい値になることがあります。
関連トピック
最終更新日: 2025 年 11 月 04 日