ApacheTapestry-コンポーネント
前に説明したように、コンポーネントとページは同じですが、ページがルートコンポーネントであり、1つ以上の子コンポーネントが含まれている点が異なります。コンポーネントは常にページ内に存在し、ページのほとんどすべての動的機能を実行します。
タペストリーコンポーネントは、複雑なグリッド機能への単純なHTMLリンクをレンダリングします。 interactive AJAX。コンポーネントには、別のコンポーネントを含めることもできます。タペストリーのコンポーネントは、次のアイテムで構成されています-
Component Class −コンポーネントのメインJavaクラス。
XML Template−XMLテンプレートはPageテンプレートに似ています。コンポーネントクラスは、テンプレートを最終出力としてレンダリングします。一部のコンポーネントにはテンプレートがない場合があります。この場合、出力は、を使用してコンポーネントクラス自体によって生成されます。MarkupWriter クラス。
Body−ページテンプレート内で指定されたコンポーネントにはカスタムマークアップがある場合があり、これは「コンポーネント本体」と呼ばれます。コンポーネントテンプレートに<body />要素の場合、<body />要素はコンポーネントの本体に置き換えられます。これは、XMLテンプレートのセクションで前述したレイアウトに似ています。
Rendering −レンダリングは、コンポーネントのXMLテンプレートと本体をコンポーネントの実際の出力に変換するプロセスです。
Parameters −コンポーネントとページ間の通信を作成し、それによってそれらの間でデータを渡すために使用されます。
Events−コンポーネントからそのコンテナ/親(ページまたは別のコンポーネント)に機能を委任します。これは、ページナビゲーションの目的で広く使用されています。
レンダリング
コンポーネントのレンダリングは、一連の事前定義されたフェーズで行われます。コンポーネントシステムの各フェーズには、コンポーネントクラスの規則またはアノテーションによって定義された対応するメソッドが必要です。
// Using annotaion
@SetupRender
void initializeValues() {
// initialize values
}
// using convention
boolean afterRender() {
// do logic
return true;
}
フェーズ、そのメソッド名、およびそのアノテーションを以下に示します。
注釈 | デフォルトのメソッド名 |
---|---|
@SetupRender | setupRender() |
@BeginRender | beginRender() |
@BeforeRenderTemplate | beforeRenderTemplate() |
@BeforeRenderBody | beforeRenderBody() |
@AfterRenderBody | afterRenderBody() |
@AfterRenderTemplate | afterRenderTemplate() |
@AfterRender | afterRender() |
@CleanupRender | cleanupRender() |
各フェーズには特定の目的があり、次のとおりです。
SetupRender
SetupRenderは、レンダリングプロセスをキックスタートします。通常、コンポーネントのパラメータを設定します。
BeginRender
BeginRenderは、コンポーネントのレンダリングを開始します。通常、コンポーネントの開始/開始タグをレンダリングします。
BeforeRenderTemplate
BeforeRenderTemplateは、XMLテンプレートを装飾するために使用され、テンプレートの周囲に特別なマークアップを追加します。また、テンプレートのレンダリングをスキップするオプションもあります。
BeforeRenderBody
BeforeRenderTemplateは、コンポーネントのbody要素のレンダリングをスキップするオプションを提供します。
AfterRenderBody
AfterRenderBodyは、コンポーネントの本体がレンダリングされた後に呼び出されます。
AfterRenderTemplate
AfterRenderTemplateは、コンポーネントのテンプレートがレンダリングされた後に呼び出されます。
AfterRender
AfterRenderはBeginRenderの対応物であり、通常は終了タグをレンダリングします。
CleanupRender
CleanupRenderは、SetupRenderに相当します。レンダリングプロセス中に作成されたすべてのオブジェクトを解放/破棄します。
レンダリングフェーズのフローは順方向だけではありません。フェーズの戻り値に応じて、フェーズ間を行き来します。
たとえば、SetupRenderメソッドがfalseを返す場合、レンダリングはCleanupRenderフェーズにジャンプし、その逆も同様です。異なるフェーズ間のフローを明確に理解するには、下の図のフローを確認してください。
シンプルなコンポーネント
「Hello、Tapestry」という出力メッセージを持つ単純なコンポーネントHelloを作成しましょう。以下は、Helloコンポーネントとそのテンプレートのコードです。
package com.example.MyFirstApplication.components;
public class Hello {
}
<html
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<div>
<p>Hello, Tapestry (from component).</p>
</div>
</html>
Helloコンポーネントは、ページテンプレートで次のように呼び出すことができます。
<html title = "Hello component test page"
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<t:hello />
</html>
同様に、コンポーネントは、以下に示すように、テンプレートの代わりにMarkupWriterを使用して同じ出力をレンダリングする場合があります。
package com.example.MyFirstApplication.components;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.annotations.BeginRender;
public class Hello {
@BeginRender
void renderMessage(MarkupWriter writer) {
writer.write("<p>Hello, Tapestry (from component)</p>");
}
}
以下のコードブロックに示すように、コンポーネントテンプレートを変更し、<body />要素を含めましょう。
<html>
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<div>
<t:body />
</div>
</html>
これで、以下に示すように、ページテンプレートのコンポーネントマークアップに本文が含まれる場合があります。
<html title = "Hello component test page"
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<t:hello>
<p>Hello, Tapestry (from page).</p>
</t:hello>
</html>
出力は次のようになります-
<html>
<div>
<p>Hello, Tapestry (from page).</p>
</div>
</html>
パラメーター
これらのパラメータの主な目的は、コンポーネントのフィールドとページのプロパティ/リソースの間に接続を作成することです。パラメータを使用して、コンポーネントとそれに対応するページは相互に通信し、データを転送します。これはTwo Way Data Binding。
たとえば、ユーザー管理ページで年齢を表すために使用されるテキストボックスコンポーネントは、パラメーターを介して初期値(データベースで利用可能)を取得します。この場合も、ユーザーの年齢が更新されて送信された後、コンポーネントは同じパラメーターを介して更新された年齢を送り返します。
コンポーネントクラスに新しいパラメータを作成するには、フィールドを宣言して、 @Parameter注釈。この@Parameterには、2つのオプションの引数があります。
required−パラメータを必須にします。タペストリーが提供されていない場合、例外が発生します。
value −パラメータのデフォルト値を指定します。
パラメータは、コンポーネントタグの属性としてページテンプレートで指定する必要があります。属性の値は、前の章で説明したバインディング式/展開を使用して指定する必要があります。以前に学んだ拡張のいくつかは次のとおりです。
Property expansion (prop:«val») −ページクラスのプロパティからデータを取得します。
Message expansion (message:«val») −index.propertiesファイルで定義されたキーからデータを取得します。
Context expansion (context:«val») −Webコンテキストフォルダ/ src / main / webappからデータを取得します。
Asset expansion (asset:«val») −jarファイル/ META-INF / assetsに埋め込まれているリソースからデータを取得します。
Symbol expansion (symbol:«val») −AppModule.javafileで定義されているシンボルからデータを取得します。
タペストリーにはさらに多くの便利な拡張があり、その一部を以下に示します。
Literal expansion (literal:«val») −リテラル文字列。
Var expansion (var:«val») −コンポーネントのレンダリング変数の読み取りまたは更新を許可します。
Validate expansion (validate:«val»)−オブジェクトの検証ルールを指定するために使用される特殊な文字列。たとえば、validate:required、minLength = 5のようになります。
Translate (translate:«val») −入力検証でTranslatorクラス(クライアント側からサーバー側の表現への変換)を指定するために使用されます。
Block (block:«val») −テンプレート内のブロック要素のID。
Component (component:«val») −テンプレート内の別のコンポーネントのID。
プロパティ拡張とVar拡張を除いて、上記のすべての拡張は読み取り専用です。これらは、ページとデータを交換するためにコンポーネントによって使用されます。属性値として展開を使用する場合、${...}使用しないでください。代わりに、ドルと中括弧の記号なしで展開を使用してください。
パラメータを使用するコンポーネント
Helloコンポーネントを変更して、新しいコンポーネントHelloWithParameterを作成し、メッセージを動的にレンダリングします。 name コンポーネントクラスのパラメータと、それに応じてコンポーネントテンプレートとページテンプレートを変更します。
新しいコンポーネントクラスを作成する HelloWithParameter.java。
プライベートフィールドを追加し、 @Parameter注釈。必須の引数を使用して必須にします。
@Parameter(required = true)
private String name;
プライベートフィールドを追加し、結果を @Propery注釈。結果プロパティは、コンポーネントテンプレートで使用されます。コンポーネントテンプレートは、注釈が付けられたフィールドにアクセスできません@Parameter 注釈付きのフィールドにのみアクセスできます @Property。コンポーネントテンプレートで使用できる変数は、レンダリング変数と呼ばれます。
@Property
private String result;
RenderBodyメソッドを追加し、nameパラメーターからresultプロパティに値をコピーします。
@BeginRender
void initializeValues() {
result = name;
}
新しいコンポーネントテンプレートを追加します HelloWithParamter.tml そして、resultプロパティを使用してメッセージをレンダリングします。
<div> Hello, ${result} </div>
テストページ(testhello.java)に新しいプロパティUsernameを追加します。
public String getUsername() {
return "User1";
}
ページテンプレートで新しく作成されたコンポーネントを使用し、のnameパラメータでUsernameプロパティを設定します。 HelloWithParameter 成分。
<t:helloWithParameter name = "username" />
完全なリストは次のとおりです-
package com.example.MyFirstApplication.components;
import org.apache.tapestry5.annotations.*;
public class HelloWithParameter {
@Parameter(required = true)
private String name;
@Property
private String result;
@BeginRender
void initializeValues() {
result = name;
}
}
<html
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<div> Hello, ${result} </div>
</html>
package com.example.MyFirstApplication.pages;
import org.apache.tapestry5.annotations.*;
public class TestHello {
public String getUsername() {
return "User1";
}
}
<html title = "Hello component test page"
xmlns:t = "https://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<t:helloWithParameter name = "username" />
</html>
結果は次のようになります-
<div> Hello, User1 </div>
高度なパラメータ
前の章では、カスタムコンポーネントで単純なパラメータを作成して使用する方法を分析しました。高度なパラメータには、完全なマークアップも含まれる場合があります。この場合、マークアップは、ページテンプレートのサブセクションなどのコンポーネントタグ内で指定する必要があります。組み込みのifコンポーネントには、成功条件と失敗条件の両方のマークアップがあります。成功のマークアップはコンポーネントタグの本体として指定され、失敗のマークアップはelseparameter。
使い方を見てみましょう if成分。ifコンポーネントには2つのパラメーターがあります-
test −単純なプロパティベースのパラメータ。
Else −条件が失敗した場合に、代替マークアップを指定するために使用される高度なパラメーター
Tapestryは、次のロジックを使用してテストプロパティの値をチェックし、trueまたはfalseを返します。これはType Coercion、あるタイプのオブジェクトを同じコンテンツを持つ別のタイプに変換する方法。
データ型が String、リテラル文字列「False」(大文字と小文字を区別しない)ではなく、空白でない場合は「True」。
データ型が Number、ゼロ以外の場合はTrue。
データ型が Collection、空でない場合はTrue。
データ型が Object、True(nullでない限り)。
条件が満たされると、コンポーネントはそのボディをレンダリングします。それ以外の場合は、elseパラメーターの本体をレンダリングします。
完全なリストは次のとおりです-
package com.example.MyFirstApplication.pages;
public class TestIf {
public String getUser() {
return "User1";
}
}
<html title = "If Test Page"
xmlns:t = "http://tapestry.apache.org/schema/tapestry_5_4.xsd"
xmlns:p = "tapestry:parameter">
<body>
<h1>Welcome!</h1>
<t:if test = "user">
Welcome back, ${user}
<p:else>
Please <t:pagelink page = "login">Login</t:pagelink>
</p:else>
</t:if>
</body>
</html>
コンポーネントイベント/ページナビゲーション
タペストリーアプリケーションは collection of Pages互いに相互作用します。これまで、ページ間の通信なしで個々のページを作成する方法を学びました。コンポーネントイベントの主な目的は、サーバー側のイベントを使用してページ間(ページ内も)の相互作用を提供することです。コンポーネントイベントのほとんどは、クライアント側のイベントから発生します。
たとえば、ユーザーがページ内のリンクをクリックすると、Tapestryは、ターゲットページを呼び出す代わりに、ターゲット情報を使用して同じページ自体を呼び出し、サーバー側のイベントを発生させます。タペストリーページはイベントをキャプチャし、ターゲット情報を処理し、サーバー側でターゲットページにリダイレクトします。
タペストリーは Post/Redirect/Get (RPG) design patternページナビゲーション用。RPGでは、ユーザーがフォームを送信してPOSTリクエストを行うと、サーバーは投稿されたデータを処理しますが、応答を直接返しません。代わりに、別のページへのクライアント側のリダイレクトを実行し、結果を出力します。RPGパターンは、ブラウザの戻るボタンやブラウザの更新ボタンなどによるフォームの重複送信を防ぐために使用されます。Tapestryは、次の2種類のリクエストを提供することでRPGパターンを提供します。
Component Event Request−このタイプのリクエストは、ページ内の特定のコンポーネントを対象とし、コンポーネント内でイベントを発生させます。この要求はリダイレクトのみを行い、応答を出力しません。
Render Request −これらのタイプの要求はページを対象とし、応答をクライアントにストリーミングします。
コンポーネントイベントとページナビゲーションを理解するには、タペストリーリクエストのURLパターンを知る必要があります。両方のタイプのリクエストのURLパターンは次のとおりです-
Component Event Requests −
/<<page_name_with_path>>.<<component_id|event_id>>/<<context_information>>
Render Request −
/<<page_name_with_path>>/<<context_information>>
URLパターンの例のいくつかは次のとおりです。
インデックスページは、 https://«domain»/«app»/index。
インデックスページがサブフォルダ管理者の下で利用できる場合、それはによって要求することができます https://«domain»/«app»/admin/index。
ユーザーがクリックした場合 ActionLink component と id test インデックスページでは、URLは次のようになります https://«domain»/«app»/index.test。
イベント
デフォルトでは、タペストリーは発生します OnPassivate そして OnActivateすべてのリクエストのイベント。コンポーネントイベントリクエストタイプの場合、タペストリーはコンポーネントに応じて追加の1つ以上のイベントを発生させます。ActionLinkコンポーネントはActionイベントを発生させますが、Formコンポーネントは次のような複数のイベントを発生させます。Validate, Success、など、
イベントは、対応するメソッドハンドラーを使用してページクラスで処理できます。メソッドハンドラーは、メソッドの命名規則または@OnEvent注釈。メソッドの命名規則の形式は次のとおりです。On«EventName»From«ComponentId»。
ActionLinkコンポーネントのアクションイベント id test 次のいずれかの方法で処理できます-
void OnActionFromTest() {
}
@OnEvent(component = "test", name = "action")
void CustomFunctionName() {
}
メソッド名に特定のコンポーネントがない場合、一致するイベントを持つすべてのコンポーネントに対してメソッドが呼び出されます。
void OnAction() {
}
OnPassivateおよびOnActivateイベント
OnPassivateは、OnActivateイベントハンドラーのコンテキスト情報を提供するために使用されます。一般に、Tapestryはコンテキスト情報を提供し、OnActivateeventハンドラーの引数として使用できます。
たとえば、コンテキスト情報がint型の3の場合、OnActivateイベントは次のように呼び出すことができます。
void OnActivate(int id) {
}
シナリオによっては、コンテキスト情報が利用できない場合があります。この状況では、OnPassivateイベントハンドラーを介してOnActivateイベントハンドラーにコンテキスト情報を提供できます。OnPassivateイベントハンドラーの戻り値の型は、OnActivateイベントハンドラーの引数として使用する必要があります。
int OnPassivate() {
int id = 3;
return id;
}
void OnActivate(int id) {
}
イベントハンドラの戻り値
Tapestryは、イベントハンドラーの戻り値に基づいてページリダイレクトを発行します。イベントハンドラは、次のいずれかの値を返す必要があります。
Null Response−null値を返します。Tapestryは現在のページのURLを作成し、リダイレクトとしてクライアントに送信します。
public Object onAction() {
return null;
}
String Response−文字列値を返します。Tapestryは、値に一致するページのURLを作成し、リダイレクトとしてクライアントに送信します。
public String onAction() {
return "Index";
}
Class Response−ページクラスを返します。Tapestryは、返されたページクラスのURLを作成し、リダイレクトとしてクライアントに送信します。
public Object onAction() {
return Index.class
}
Page Response− @ InjectPageアノテーションが付けられたフィールドを返します。Tapestryは、挿入されたページのURLを作成し、リダイレクトとしてクライアントに送信します。
@InjectPage
private Index index;
public Object onAction(){
return index;
}
HttpError−HTTPErrorオブジェクトを返します。Tapestryはクライアント側のHTTPエラーを発行します。
public Object onAction(){
return new HttpError(302, "The Error message);
}
Link Response−リンクインスタンスを直接返します。TapestryはLinkオブジェクトからURLを作成し、リダイレクトとしてクライアントに送信します。
Stream Response −を返します StreamResponseオブジェクト。Tapestryは、ストリームを応答としてクライアントブラウザに直接送信します。レポートと画像を直接生成し、クライアントに送信するために使用されます。
Url Response −を返します java.net.URLオブジェクト。Tapestryは、オブジェクトから対応するURLを取得し、リダイレクトとしてクライアントに送信します。
Object Response−上記の指定値以外の値を返します。タペストリーはエラーを発生させます。
イベントコンテキスト
一般に、イベントハンドラーは、引数を使用してコンテキスト情報を取得できます。たとえば、コンテキスト情報がint型の3の場合、イベントハンドラは次のようになります。
Object onActionFromTest(int id) {
}
Tapestryはコンテキスト情報を適切に処理し、引数を介してメソッドに提供します。プログラミングが複雑なため、Tapestryが適切に処理できない場合があります。その時点で、完全なコンテキスト情報を取得して自分で処理する場合があります。
Object onActionFromEdit(EventContext context) {
if (context.getCount() > 0) {
this.selectedId = context.get(0);
} else {
alertManager.warn("Please select a document.");
return null;
}
}