bind (マクロ)
インポート元: CURL.GUI.STANDARD. package 内で定義されています CURL.GUI.BASE.

DataBinding を作成する簡単なマクロ形式。

構文

        {bind 
                property-name 
                [at [target-var[:target-type] =]
                 [target-val]
                ]
                to data-selector 
                [in [context-var[:context-type] =] 
                 [context-val]
                ]
                [as binding-var]
                [, default-value = default-val]
                [,{format [data-var:[data-type] as] 
                      format-body
                  }
                ]
                [, {parse [property-var:[property-type] as]
                       parse-body
                   }
                ]
                [, {report 
                       parse-body
                   }
                ]
                [, allow-update?=true/false]    
                [, auto-register?=true/false]    
            }
        
このマクロが作成するオブジェクトは、関連 targetproperty-name プロパティを関連 contextdata-selector で表されるデータに同期させます。
data-selector で表されるデータが変化するたびに、ターゲット プロパティのコンテキストは自動的にリフレッシュされます。さらに、DataBinding.refresh または DataBindingContext.refresh を呼び出して強制的にリフレッシュを行うこともできます。
allow-update? プロパティが true の場合は (既定値)、DataBindingContext.update メソッドを呼び出してターゲットへの変更をコンテキストに書き込むことができます。変更内容は、DataBindingContext.validate を呼び出して更新の前に検証することができます。
ターゲットとコンテキストの情報をそれぞれ明示的に指定するのに、atin を使用できます。この 2 つの句を使って、これらのアイテムの変数バインドを確立してマクロ内で使用します。また、これらの句を使って固定値を割り当てることもできますが、ほとんどの場合はマクロのユーザーがこれらのプロパティを動的に決定します (下記の例を参照)。
as 句は、このマクロによって生成される DataBinding の変数名を指定するのに使用されます。 関連するデータバインディングにアクセスするのに必要なformat句、parse句、そして report句を指定する際にこの変数は役立ちます。
default-value パラメータは、コンテキストに使用可能なデータがない場合に (たとえば、ソースの RecordSet が空の場合、データがロード中の場合など) プロパティが使用する値を指定します。このパラメータの既定値は DataBinding.unset で、ターゲット プロパティを「設定解除」しなければならないことを意味します。ただし、バインド プロパティには「設定解除」操作を行っても意味がないものもあり、この場合には他の値が既定値として使われます。
format 句は、コンテキストのデータ値をターゲットに適用する前に、どのように変換するかを指定します。data-val:data-type は、変換するデータにバインドするオプションの変数バインドを表します。format-body は一連のステートメントで構成され、最後のステートメントはターゲット プロパティの設定に使われます。詳細は DataBinding.format を参照してください。
parse 句は、コンテキストを更新する前にターゲット プロパティの値をどのように変換するかを指定します。これは format 句の逆を表すことになり、その構造も似ています。詳細は DataBinding.parse を参照してください。
report 句は、バインドのリフレッシュ、更新、検証の後に実行されるアクションを指定するのに使います。
auto-register? パラメータは、作成したバインドがそのターゲットの data-binding-context に自動的に登録されるかどうかを指定します。context を明示的に指定しない場合は既定により true になり、その他の場合は false になります。

説明

このマクロへの入力値に関する詳細は、DataBinding を参照してください。

次のコードは VisualRecordForm にどのようにバインドされるかを示しています。わかりやすく示すために、フォームの record-source がユーザー データの RecordSet で、これには "user-name" (String) と "account-balance" (double) というフィールドが含まれているという前提にしています。
最も簡単なバインドの例は、次のように TextDisplay をバインドして "user-name" の内容を表示するものです。RecordForm が必要とする data-selector はフィールド名だけである点に注意してください。
{RecordForm
    record-source = user-records,
    ...
    {TextDisplay
        {bind value to "user-name"}
    }
}
もう少し複雑なシナリオとしては、コンテキストとターゲット間のデータ変換が考えられます。この場合、次に示すように 1 つの DataBindingTarget に複数のバインドを適用することができます。
{RecordForm
    record-source = user-records,
    ...
    {TextDisplay
        {bind value to "account-balance"},
        {bind color to "account-balance",
            {format balance:double as
                {if balance < 0 then "red" else "black"}
            }
        } 
    }
}
一般的なシナリオでは、ValueControlvalue プロパティにバインドし、このコントロールを使ってコンテキストのデータ更新や表示を行うというものです。これは最後の例で、bind マクロの検証/レポート拡張機能をいくつか使用して示しています。この例では特に次の点を表しています。
  • ターゲット (tf:TextField)、コンテキスト (rf:RecordForm) およびバインド自体 (binding) の変数名と型を宣言する。
  • parse 句を使用して、RecordForm が実行する検証に検証を追加する。
  • report 句を使用して、ユーザーに検証結果を表示する。
{RecordForm
    record-source = user-records,
    ...
    {TextField
        {bind value at tf:TextField to 
            "user-name" in rf:RecordForm
            as binding, 
            {parse val:String as
                {if val.length < 10 then
                    {DataBindingValidationFailure 
                        "Name must contain at least ten characters"
                    }
                 else
                    val
                }
            },
            {report
                {if-non-null err = binding.validation-failure then
                    {popup-message err.value}
                    set tf.color = "red"
                 else
                    set tf.color = "black"
                }
            }
        }
    }
}