カスタムコントロール プロパティ定義にNotesDocumentを渡す方法

XPages開発でカスタムコントロールによる設計の分離を行う際、StringやBoolean意外にもNotesDocumentなどのデータソースをプロパティ定義する方法をご紹介します。

カスタムコント,ロールにデータソースを渡したい場面

そもそも、XPage本体でデータソースを定義していればNotesXSPDocument(デフォルトでは”document1″としてアクセス可)はカスタムコントロール側でも同様の方法でアクセスが可能になっています。
document1.getDocument() としてやればNotesDocumentへもアクセスが可能です。

ではNotesDocumentをカスタムコントロールに渡す必要があるシチュエーションというのはどのような場面でしょうか?

一番想定されるケースとして、ビューやRepeatコントロール内で各文書データを出力(もしくは編集)させるカスタムコントロールの作成です。

こちらにデモ用のサンプルを作ってみました。

サンプルURL: http://minato.ktrick.com/demo.nsf/ccWithNdocProperty.xsp

サンプルではテーブル内で文書がある分だけRepeatコントロールで行出力します。各文書の詳細情報として各行の下の緑のエリアがカスタムコントロールで実装している箇所です。

カスタムコントロールでデータソースをプロパティ定義

以下のようにしてカスタムコントロールでデータソースをプロパティ定義してやります。

  1. カスタムコントロールを作成
  2. 「Property Definition(プロパティ定義)」から「New Property(新しいプロパティ)」をクリック
  3. 「Name(名前)」に任意の名前をつけます
  4. 「Type(タイプ)」から右のアイコンをクリック
  5. 「Data Source(データソース)」から「Domino Document(Domino文書)」を選択
  6. 「Editor(エディター)」から右のアイコンをクリックし「Deta」⇒「Data Source Picker」を選択します。

以上でカスタムコントロールでデータソース定義は完了です。 ここで重要になるのは「Editor(エディター)」の部分で「Data Source Picker」を選択してやることです。

サンプルXPAGEの解説

サンプルXPageのコードからカスタムコントロールで定義したデータソースの呼び出し方、使い方をみていきます。

まずは呼び出し元になるXPageのソースコードです。

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
	xmlns:xc="http://www.ibm.com/xsp/custom">
	<xp:this.data>
		<xp:dominoView var="view1" viewName="AllContacts" />
	</xp:this.data>

	<xp:div style="margin:20px;">
		<xp:table style="width:50%;">
			<xp:tr>
				<th>ID</th>
				<th>First name</th>
				<th>Last name</th>
			</xp:tr>
			<xp:repeat id="repeat1" rows="30" value="#{view1}" var="entry">
				<xp:tr>
					<xp:td>
						<xp:text escape="true" id="computedField1" value="#{entry.Id}"></xp:text>
					</xp:td>
					<xp:td>
						<xp:text escape="true" id="computedField2" value="#{entry.FirstName}"></xp:text>
					</xp:td>
					<xp:td>
						<xp:text escape="true" id="computedField3" value="#{entry.LastName}"></xp:text>
					</xp:td>
				</xp:tr>
				<xp:tr>
					<xp:td colspan="3">
						<xc:ccNdocProperty ndoc="#{javascript:entry.getDocument()}">
						</xc:ccNdocProperty>
					</xp:td>
				</xp:tr>
			</xp:repeat>
		</xp:table>
	</xp:div>
</xp:view>

29行目でカスタムコントロールを呼び出しています。先ほど作ったndocのプロパティにRepeatコントロールでループさせている各行の文書を設定しています。

以下はカスタムコントロールのソースコードです。

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
	<xp:panel style="border:5px dotted #00efef; background-color:#00dfdf; margin-left:20px; margin-bottom:20px;">
		State: <xp:text escape="true" id="computedField3" value="#{compositeData.ndoc.state}"></xp:text>
		<br />
		City: <xp:text escape="true" id="computedField1" value="#{compositeData.ndoc.city}"></xp:text>
		<br />
		Email:
		<xp:text escape="true" id="computedField2">
			<xp:this.value><![CDATA[#{javascript:compositeData.ndoc.getItemValueString("email")}]]></xp:this.value>
		</xp:text>
	</xp:panel>
</xp:view>

4行目、6行目のようにcompositeData.ndoc.city と記述してデータソースバインディングしてやることもできますし、9行目のようにcompositeData.ndoc.getItemValueString(“email”) とSSJSで記述する方法も可能です。 処理速度としてはcompositeData.ndoc.xxx のデータバインディングの方が早いはずです。

サンプルXPAGEの解説

特に高度なテクニックを使っているわけではなくXPagesが持つ標準の機能の説明になりますが、意外とこのような利用方法ができることを書かれていたブログがなかったため書いてみました。 サンプルのようなシチュエーションで今回の方法を知らなければ、文書UNIDなどを渡してカスタムコントロール側で再度NotesDocumentを取得しなおす、といった回りくどい実装をしている場合もあるかもしれません。サーバー負荷、処理速度を考えてもこのように実装したほうがスマートなケースになりますので覚えておいてもらえればと思います。