Visualforceテンプレートを使ったコード再利用

上級試験には、Apexクラスのコード再利用だけでなく、VisualForceの再利用についても問われます。
ちょっと作り方がややこしく、覚えるのに時間がかかったので、備忘も兼ねてメモります。

スポンサーリンク

まずは作り方から

VisualForceテンプレートの作りかたがまずは分からなかったので、開発者ガイドさんの力を借りて同じコードを使用することにしました。

作成の為には、apex:compositionタグ、apex:defineタグ、apex:insertタグを使って実現するみたいです。

まずは、Apexコントローラー。
こちらは、書き方は変わらないので、従来のVisualForceのコントローラのように記述すればOKです。

compositionExample.cls

public class compositionExample{

    String name;
    Integer age;
    String meal;
    String color;
    
    Boolean showGreeting = false;
    
    public PageReference save() {
        showGreeting = true;
        return null;
    }
    
    public void setNameField(String nameField) {
        name = nameField;
    }
    
    public String getNameField() {
        return name;
    }
    
    public void setAgeField(Integer ageField) {
        age= ageField;
    }
    
    public Integer getAgeField() {
        return age;
    }
    
    public void setMealField(String mealField) {
        meal= mealField;
    }
    
    public String getMealField() {
        return meal;
    }   
         
    public void setColorField(String colorField) {
        color = colorField;
    }
    
    public String getColorField() {
        return color;
    }       
    
    public Boolean getShowGreeting() {
        return showGreeting;
    }
}

次にテンプレートとなるVisualForceを作ります。
これをスケルトンテンプレートと言うそうな。
テンプレート用のVisualForceページはというと、apex:insertタグを使用して記述する必要があります。
タグの中身は特に記載は必要ありませんが、必ず名前(name)をつけてください。
ということで、こちらがテンプレートとなる VisualForceページ。

myFullForm.page

<apex:page controller="compositionExample">
    <apex:form >
        <apex:outputLabel value="Enter your name: " for="nameField"/>
        <apex:inputText id="nameField" value="{!nameField}"/>
        <br />
        <apex:insert name="age" />
        <br />
        <apex:insert name="meal" />
        <br />      
        <p>That's everything, right?</p>
        <apex:commandButton action="{!save}" value="Save" id="saveButton"/>
    </apex:form>
</apex:page>

最後にテンプレートを呼び出すためのVisualForceページ。
こちらは、apex:compositionタグを使用してテンプレートを呼び出し、apex:defineタグを使用してapex:insertタグ部分に埋め込むコンポーネントを定義します。

myFullForm.page

<apex:page controller="compositionExample">
<apex:messages/>
<apex:composition template="myFormComposition">

<apex:define name="meal">
<apex:outputLabel value="Enter your favorite meal: " for="mealField"/>
<apex:inputText id="mealField" value="{!mealField}"/>
</apex:define>

<apex:define name="age">
<apex:outputLabel value="Enter your age: " for="ageField"/>
<apex:inputText id="ageField" value="{!ageField}"/>
</apex:define>

<apex:outputLabel value="Enter your favorite color: " for="colorField"/>
<apex:inputText id="colorField" value="{!colorField}"/>

</apex:composition>

<apex:outputText id="greeting" rendered="{!showGreeting}" value="Hello {!nameField}.
You look {!ageField} years old. Would you like some {!colorField} {!mealField}?"/>
</apex:page>

結果の表示はこうなる

早速作成したmyFullFormで画面表示してみると。

こういう感じの表示になります。

よく見ると、「Enter your favorite color:」の部分がありませんね

これは、apex:compositionタグの中身がテンプレートに置き換わっていて、テンプレートの中のapex:insertタグにapex:defineタグで指定したコンポーネントが埋め込まれるので、それ以外でapex:compositionタグ直下に記載したコンポーネントはテンプレートに上書きされ無視されてしまうんですね。

なので、apex:compositionタグを使用する場合は、apex:defineタグだけを定義すれば良いことになります。

図解するとこんな感じでしょうか。

テンプレートを使用したVisualforceイメージ

まとめ

まとめというより、タグの使い方のおさらいです。

おそらくテストではここさえ押さえておけば大丈夫かと。

apex:compotsitionタグ

テンプレートを呼び出す。templete属性には呼び出すテンプレートのVisualForce名を入れる。

apex:insertタグ

テンプレート側で使用する。テンプレート内で動的に変更したいコンポーネントがある場合に、埋め込む位置にapex:insertタグを記載しておき、呼び出す際にコンポーネントをセットする。複数設置可能、必ずname属性に一意の名前をつける。

apex:defineタグ

apex:compotsitionタグの配下で使用、テンプレートの apex:insert部分に挿入するコンポーネントを定義する。name属性にはapex:insertタグのname属性を指定する。

コメント