Class | CGIKit::DynamicElement |
In: |
docs/rdoc_ja.rb
|
Parent: | CGIKit::Element |
CGIKit::DynamicElementは、エレメントの抽象クラスです。 エレメントはコンポーネントの情報を使って部分的なHTMLを生成するオブジェクトです。
エレメントとコンポーネントはどちらも動的にHTMLを生成しますが、 次の点において異なります。
まず、エレメントはステートレスなオブジェクトです。 エレメントが使われるのはリクエスト・レスポンスループ間です。 エレメントはループの各フェーズごとにコンポーネントから 必要な情報を取得すればよく、コンポーネントのように HTTPトランザクションを超えて状態を維持する必要はありません。
次にエレメントの目的は部分的にHTMLを生成することであって、 ページ全体を表示することではありません。 エレメントを組み合わせて最終的にページを構成するのはコンポーネントの役割です。
最後の点はパフォーマンスです。 前述の理由から、エレメントのパフォーマンスは 多くの処理が必要なコンポーネントよりも高くなります。 また、実装もパフォーマンスを追求するものになります。
CGIKit::DynamicElementのサブクラスを作ります。
エレメントにバインドされた属性値にアクセスするには次のメソッドを使います。
エレメントの主な実装は、ループで実行されるメソッドです。 各メソッドの役割に沿ってオーバーライドしてください。
フォームデータを扱うエレメントであれば、ここでコンポーネントに代入します。 次のメソッドが便利です。
アクションを実行するエレメントであれば、ここでアクションを実行します。 エレメントがクリックされたかどうかを確認するには、コンテキストIDを比較します。 コンテキストIDは、送信ボタンをクリックしたときはフォームデータに、 リンクをクリックしたときはURLに含まれます。 次のメソッドで確認します。
アクションを実行した場合、その戻り値を返す必要があります。
HTMLを生成し、レスポンスにセットします。
このメソッドを実装する上で注意することは、必ずしも take_values_from_request, invoke_action, append_to_response がすべて呼ばれるとは限らないことです。 invoke_action が Component オブジェクトか Response オブジェクトを返した場合、そのエレメントの append_to_response は呼ばれません。 同様に、制御の移ったコンポーネントでは append_to_response だけが呼ばれることになります。 (Elementを参照)
そのため、 append_to_response での実装は その前のフェーズの状態に依存しないようにする必要があります。 エレメントのインスタンス変数を使うのを避け、 その都度 take_value などで コンポーネントから属性値を取得するようにします。
コンテキストIDを調整して、リクエストされたエレメントを 特定できるようにする必要があります。 コンテキストIDについてはElement, Contextも参照してください。
コンテキストIDの操作には、主に次のメソッド (Context) を使います。
increment: | 最後の数字を増やします。引数を与えると最後の桁をその値に変更します。 |
append_zero: | ゼロを追加して桁を増やします。 |
delete: | 最後の桁を削除します。 |
in_form: | フォーム (form要素) を出力するエレメントであれば真を設定します。 |
コンテキストIDを準備します。 エレメントの性質によって操作が異なります。
空要素: | 最後の数字を増やします。デフォルトの実装なので、 オーバーライドする必要はありません。 |
内容を持つ要素: | 最後の数字を増やしてから、桁を追加します。 |
name属性を使う場合: | 最後の桁をname属性値にします。 |
コンテキストIDの終了処理を行います。 コンテキストIDはそのまま次のエレメントに持ち越されるので、 桁を追加した場合はここで削除しておきます。
空要素: | 特別な処理は必要はありません。 |
内容を持つ要素: | 追加した桁を削除します。 |
name属性を使う場合: | 特別な処理は必要はありません。 |
ここでいうAPIはエレメントクラスのメソッドではなく、属性の仕様のことです。 エレメントが使用する属性や、属性を組み合わせるルールなどを記述します。 代入可能な変数をバインドする属性に変数以外をバインドしたり、 間違った属性を組み合わせたりすると、実行時にエラーとなります。
現在の実装では、自分でAPIオブジェクトを組み立てる必要があります。 create_api クラスメソッドをオーバーライドし、 CGIKit::APIオブジェクトを返すよう実装します。
application | [RW] | CGIKit::Applicationオブジェクト。 |
context_id | [RW] | コンテキストID。 |
name | [RW] | バインディング定義名。 |
parent | [RW] | 親コンポーネント。 |
root | [RW] | ルートコンポーネント。 |
values | [RW] | 属性値のハッシュ。 |
HTMLを生成し、responseにセットします。 デフォルトの実装では何もしません。
See Also: take_values_from_request, invoke_action
name の属性値を取得し、真偽で返します。 does_resolve が真なら、属性値がシンボルであればメソッドとみなして コンポーネントのメソッドを実行した戻り値を属性値とします。
See Also: value
string を文字コード encoding に変換するためのフックメソッドです。 文字コードを変換した文字列を返します。 デフォルトの実装では何もしません。 cgikit/lang/ja.rb をロードすると、日本語文字コード変換用に再定義されます。
See Also: encode_strings
文字列の配列 strings を文字コード encoding に変換した配列を返します。 values_from_request で、フォームデータの文字コード変換に使われます。
See Also: encode_string
文字列に含まれるHTML制御文字をエスケープした文字列を返します。 escape が偽であれば、文字列をエスケープせずにそのまま返します。
See Also: CGIKit::Utilities#escape_html
アクションメソッドを実行します。 デフォルトの実装では、ノードの同メソッドを実行します。
See Also: take_values_from_request, append_to_response
アクション用に属性値を取得します。 name 名の属性値を評価せずに返します。 take_value(name, false) と同じです。
See Also: take_value
bool() で name の属性値を取得し、 @values にセットします。
See Also: take_value
value() で name の属性値を取得し、 @values にセットします。
See Also: take_bool, value
value() で name の属性値を取得し、 @values にセットします。 ただし一度しか属性値を取得せず、二度以上実行しても何もしません。
See Also: take_value
URLに埋め込むクエリデータのハッシュを返します。 name 名の属性値と、属性名が ? で始まる属性の値をマージしたハッシュを返します。 ハッシュは @values にセットされます。
:Query => { ... :query => {'name'=>'Paul'} :'?part' => 'base' } take_value_query(:query) #=> {'name'=>'Paul', 'part'=>'base'}
See Also: take_value
フォームデータを代入します。 デフォルトの実装では、ノードの同メソッドを実行します。
See Also: invoke_action, append_to_response
name の属性値を取得します。 does_resolve が真なら、属性値がシンボルであればメソッドとみなして コンポーネントのメソッドを実行した戻り値を属性値とします。
See Also: bool, take_value
request のフォームデータに含まれる、 コンテキストIDが一致するデータを返します。 該当するコンテキストIDがなければ nil を返します。
See Also: values_from_request
request のフォームデータに含まれる、 コンテキストIDが一致するデータを配列で返します。 フォームデータが文字列の場合、 Application#encoding に指定した 文字コードに変換されます。
See Also: encode_strings, value_from_request