プロパティとバインディング

GUI を使用してアプリケーションを開発するときの最も一般的なタスクは、ユーザー インターフェースとデータの同期を維持することです。たとえば、従来の開発ツールを使用して、顧客レコードの表示と編集を行うウェブ アプリケーションを作成するとします。App Maker を使用しない場合は、次のように、アプリケーションの UI とデータベースのレコードを同期する方法を開発しなければなりません。

  1. データベース内の次のレコードがリクエストされたときに、データを表示するすべての UI 要素を更新する。

  2. ユーザーの変更が顧客レコードに確実に反映されるように、すべての UI 要素に変更リスナーを追加する。

  3. 現在の顧客レコードを更新して、新しいデータを受け取る。

この処理を行うには、多くの定型コードを記述しメンテナンスする必要があり、プログラマーにとっては面倒な作業です。プログラミングの経験がなければ、大きな障害になるかもしれません。

App Maker では、このような定型コードを記述する必要はありません。バインディングを使用して、顧客レコードのプロパティとウィジェットのプロパティの同期を指定するだけで済みます。この作業はすべて、使いやすいビジュアル インターフェースで行います。残りの作業はすべて App Maker が行います。

より複雑なシナリオになると、UI 要素と値を同期するだけでは足りません。App Maker バインディングでより高度な設定が必要になります。たとえば、App Maker バインディングを使用して、現在ログインしているユーザーのメールアドレスとデータソースのクエリ パラメータなど、App Maker の 2 つのプロパティを同期させます。モデル、データソース、ウィジェット、スクリプトなど、App Maker のほぼすべての要素にバインディングがあるため、App Maker のさまざまなプロパティにバインディングを使用できます。

プロパティ

ごく簡単に言うと、プロパティは App Maker オブジェクトの名前付きです。App Maker でプロパティの値を取得し、設定できます。ほとんどの App Maker オブジェクトにプロパティが含まれ、アプリケーションからアクセスできます。

プロパティは、次の方法で設定できます。

  • App Maker の UI - ウィジェット名を設定するときに使用します。
  • バインディング - プロパティの変更が別のプロパティに反映される場合に使用します。
  • スクリプト - JavaScript でプロパティを設定できます

また、次のようなプロパティにアクセスできます。

  • データベース レコードのフィールド
  • 現在ログインしているユーザーのメールアドレス
  • 位置、名前、値などのウィジェット属性

プロパティは App Maker のどこででも操作できますが、プロパティ エディタが最も一般的です。

バインディング選択ツールでも操作できます。

オブジェクト

プロパティについて、もう少し深く調べてみましょう。ここでは、オブジェクトについて説明します。オブジェクトは、App Maker と App Maker アプリケーションの構成要素で、App Maker のほぼすべてがオブジェクトになります。具体的にどのようなものがあるのでしょうか。たとえば、UI を構成するウィジェット、データを表すレコード、データの読み取りと書き込みを行うデータソース オブジェクトなどがあります。アプリケーション自体もオブジェクトです。

たとえば、テキスト領域ウィジェットは、名前やラベルなどのプロパティを持つ App Maker オブジェクトです。データレコードはプロパティを定義するアプリケーション オブジェクトで、顧客レコードには名前プロパティを定義します。

すべての App Maker プロパティにはデータ型が指定されます。すなわち、数値や文字列など、特定の種類の値のみが受け付けられます。多くのプロパティは、文字列、数値、ブール値などの単純なデータ型を持ちますが、複雑な型を持つプロパティもあります。たとえば、ウィジェットの親プロパティもウィジェットで、Widget という型になります。

パス

App Maker は、バインディングまたはスクリプト内でプロパティを参照するときに、パス表記を使用して行います。たとえば、Name というプロパティを持つ Person というデータモデル オブジェクトは、Person.Name と参照されます。

未定義

パスとプロパティの値は undefined(未定義)にできます。これは null とは異なります。たとえば、まだ読み込まれていないレコードのリレーション プロパティは未定義になります。datasource.item.Name などのパスは、最後のプロパティ(Name)が undefined の場合、未定義になります。また、datasourceitem などの部分が undefined または null の場合も未定義になります。通常、App Maker は未定義値を null のように扱いますが、値が undefined に設定されている場合、入力ウィジェットは無効になります。たとえば、テキスト ボックスの値を消去して無効にするには、次のスクリプトを使用します。

textBox.value = undefined;
    

次の例では、PersonAddress の 2 つの複雑なプロパティについて説明します。いずれも、作成したモデルで定義できる特別な型を持ちます。これは、App Maker に組み込みの型ではありません。

Person
プロパティ名
Name文字列
Age数値
Address住所
Address
プロパティ名
Street文字列
City文字列
Zip文字列

Person の Address プロパティは住所型のため、人物の所在地を Person.Address.City というパス表記で参照します。

バインディング

バインディングとは、2 つのプロパティを同期させるメカニズムです。App Maker でアプリを作成する際に、テキスト入力の値とレコードのフィールド値など、2 つのプロパティのバインドを宣言すると、App Maker がこれらのプロパティを自動的に同期します。このような宣言はよく行われ、一方のプロパティが変更されると、それに合わせてもう一方の値が設定されます。

App Maker のすべてのプロパティは監視可能です。つまり、プロパティの変更を監視できます。2 つのプロパティをバインドすると、各プロパティの変更が監視され、一方が変更されるともう一方が更新されます。

App Maker でよく行われるのは、テキスト入力値とデータソースの item プロパティのバインディングです。このバインディングは App Maker のプロパティ エディタで行います。バインディングを最初から作成すると、次のようになります。

@widget.text <-> @datasource.item.MyField
    

バインディングされた値の型変換

プロパティは型と値から構成されます。値自体にも型があり、これはプロパティの値と一致する必要があります。たとえば、ウィジェットの Name プロパティは文字列型なので、名前の値は文字列になり、整数として扱うことはできません。

2 つのプロパティをバインドする場合、これらのプロパティが同じ型になっている必要があります。異なる場合は、一方の型をもう一方の型に変換可能でなければなりません。これを型変換といいます。

たとえば、ウィジェットの Name プロパティに値 "6" を指定した場合、この値 "6" は数値ではなく文字列として扱われます。このプロパティを整数型の別のプロパティにバインドすると、App Maker に組み込みの型変換で、これらの 2 つのプロパティ間で値の型が変換されます。

App Maker には多くの型変換が組み込まれているため、大半のバインディングは機能します。変換は双方向で機能し、型の間で値が変換されます。

型変換の前型変換の後条件
文字列数値型変換前のデータ型が数値として解析できる場合のみ。
文字列ブール値型変換前の値が true または false の場合のみ(大文字と小文字は区別されません)。
文字列日付型変換前の値が YYYY-MM-DD 形式の日付の場合のみ。
数値ブール値ゼロは false に、その他の値は true に変換されます。
配列<A>配列<B>A と B に互換性がある場合のみ。

トランスフォーマー

カスタムデータ変換を行ってから 2 つのプロパティをバインドしたい場合もあります。たとえば、レコード内のフィールドを UI のテキスト フィールドにバインドする場合、データベースに保存する前に入力から空白文字を削除できます。また、App Maker のデフォルトの型変換とは異なるパターンで日付を文字列に変換することもできます。トランスフォーマーを使用すると、プロパティパスで変換を指定できます。各トランスフォーマーは入力値から出力値を生成します。ほとんどのトランスフォーマーは、出力値から元に入力値に戻すこともできます。これらの変換を連鎖させることもできます。たとえば、文字列パスの入力と出力から空白文字を削除するには、テキスト フィールドの value プロパティをデータソース レコードの Name フィールドにバインドします。

@value <-> @datasource.item.Name#trim()
    

テキスト フィールドの value プロパティをデータベースの日付フィールド timestamp にバインドするときに、文字列形式にカスタム日付を指定することもできます。

@value <--> @datasource.item.TimeStamp#formatDate('yyyy/MM/dd HH:mm:ss');
    

トランスフォーマーは連鎖させることができます。

@value <-> @datasource.item.Name#nullToEmpty()#trim()
    

組み込みのトランスフォーマーについては、こちらをご覧ください。

トランスフォーマーは、配列全体ではなく配列の要素にも適用できます。たとえば、プルダウン ウィジェットの name プロパティに、射影から項目を挿入しているとします。構文は同じですが、ハッシュ記号を 2 個使用します。

@names <-> @datasources.items..TimeStamp##formatDate('yyyy/MM/dd HH:mm:ss')
    

バインディングの最上位プロパティ

オブジェクトのプロパティ(ウィジェット名など)をバインドする場合、バインディング選択ツールを使用して利用可能なプロパティを選択します。App Maker は、バインド元のオブジェクトに応じて利用可能なプロパティを自動的に調整します。これにより、よく利用されるプロパティを簡単にバインドできます。たとえば、ボタン ウィジェットの値をバインドする場合、バインディング ピッカーはウィジェットの datasource.item プロパティをデフォルトに設定します。このプロパティには通常、モデルのフィールドが含まれます。

ただし、バインディング ピッカーが自動的に提示した候補以外のものにウィジェットまたは他のオブジェクトをバインドしたい場合もあります。プロパティは 2 つのカテゴリに分類できます。このカテゴリを理解しておくと、アプリケーションでオブジェクトをバインドする際に役立ちます。

グローバルに利用可能なプロパティ

アプリケーションの任意のプロパティにバインドできます。通常、これらのプロパティは app オブジェクトからアクセスされます。バインディングを行うときに、app オブジェクトのすべてのプロパティが分類され、バインディング用に公開されます。各プロパティの詳細については、アプリ オブジェクトの API ドキュメントをご覧ください。

ウィジェットで利用可能なプロパティ

ウィジェットは、app オブジェクトのすべてのプロパティと 2 つの追加プロパティにバインドできます。

  • widget - ウィジェット自体。
  • datasource - ウィジェットのデータソース。ウィジェットにバインドする最も一般的なオブジェクトです。これは @widget.datasource としても利用できますが、便宜上、datasource は UI エディタのバインディング選択ツールに表示されます。

バインディング式

2 つのプロパティを直接バインドするだけでは不十分な場合があります。App Maker UI のバインディング エディタで式を使用すると、バインディングと JavaScript を組み合わせて、バインド先の値を変換できます。式に使用されているプロパティの 1 つが変更されるたびに、App Maker はその式を評価します。注: これにより、バインディングが一方向になります。

たとえば、MyDeleteButton という名前の削除ボタンがあり、データベースに削除するレコードがない場合にボタンを無効にするように、バインディングを作成するとします。ただし、このコンセプトをそのまま表現できるプロパティはありません。ここでは、enabled プロパティと @datasource.item プロパティを使用します。アイテムがない場合、これらのプロパティの値は null になります。これらの情報を使用して、次のようにバインドできます。

@widget.enabled <-> @datasource.item != null
    

これで、レコードがある場合にのみボタンが有効になります。

参考情報

バインディング式の作成方法については、バインディング式クライアント サイド スクリプティングをご覧ください。ウィジェットとクライアント オブジェクトで使用できるプロパティとメソッドについては、ウィジェット APIクライアント API をご覧ください。