IBM Connectons PINKとDominoの未来
2017年2月21日から23日まで開催されたIBM Conn...
XPages開発でカスタムコントロールによる設計の分離を行う際、StringやBoolean意外にもNotesDocumentなどのデータソースをプロパティ定義する方法をご紹介します。
そもそも、XPage本体でデータソースを定義していればNotesXSPDocument(デフォルトでは”document1″としてアクセス可)はカスタムコントロール側でも同様の方法でアクセスが可能になっています。
document1.getDocument() としてやればNotesDocumentへもアクセスが可能です。
ではNotesDocumentをカスタムコントロールに渡す必要があるシチュエーションというのはどのような場面でしょうか?
一番想定されるケースとして、ビューやRepeatコントロール内で各文書データを出力(もしくは編集)させるカスタムコントロールの作成です。
こちらにデモ用のサンプルを作ってみました。
サンプルURL: http://minato.ktrick.com/demo.nsf/ccWithNdocProperty.xsp
サンプルではテーブル内で文書がある分だけRepeatコントロールで行出力します。各文書の詳細情報として各行の下の緑のエリアがカスタムコントロールで実装している箇所です。
以下のようにしてカスタムコントロールでデータソースをプロパティ定義してやります。
以上でカスタムコントロールでデータソース定義は完了です。 ここで重要になるのは「Editor(エディター)」の部分で「Data Source Picker」を選択してやることです。
サンプルXPageのコードからカスタムコントロールで定義したデータソースの呼び出し方、使い方をみていきます。
まずは呼び出し元になるXPageのソースコードです。
[xml highlight=”29,30″]
<?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>
[/xml]
29行目でカスタムコントロールを呼び出しています。先ほど作ったndocのプロパティにRepeatコントロールでループさせている各行の文書を設定しています。
以下はカスタムコントロールのソースコードです。
[xml highlight=”4,6,9″]
<?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>
[/xml]
4行目、6行目のようにcompositeData.ndoc.city と記述してデータソースバインディングしてやることもできますし、9行目のようにcompositeData.ndoc.getItemValueString(“email”) とSSJSで記述する方法も可能です。 処理速度としてはcompositeData.ndoc.xxx のデータバインディングの方が早いはずです。
特に高度なテクニックを使っているわけではなくXPagesが持つ標準の機能の説明になりますが、意外とこのような利用方法ができることを書かれていたブログがなかったため書いてみました。 サンプルのようなシチュエーションで今回の方法を知らなければ、文書UNIDなどを渡してカスタムコントロール側で再度NotesDocumentを取得しなおす、といった回りくどい実装をしている場合もあるかもしれません。サーバー負荷、処理速度を考えてもこのように実装したほうがスマートなケースになりますので覚えておいてもらえればと思います。