apex:action〜について【セールスフォース】

<!-- wp:paragraph -->
<p>こんにちは、アンダーソンです。<br>今回も上級デベロッパーの勉強中に気になったシリーズです。<br>Visualforceタグのapex:action〜ってやつ、みたことあると思いますが、<br>何がどんな働きをしているのかって言われてもパッと答えることができなかったので、<br>この機会にまとめてみようと思います。</p>
<!-- /wp:paragraph -->

<!-- wp:separator -->
<hr class="wp-block-separator"/>
<!-- /wp:separator -->

<!-- wp:heading {"level":3} -->
<h3>全部で5つあります</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>apex:action〜のタグは全部で5つ用意されています。</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>apex:actionFunction</li><li>apex:actionRegion</li><li>apex:actionPoller</li><li>apex:actionStatus</li><li>apex:actionSupport</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>以上5つです。それぞれがどんな働きをするのかを実際にやってみていきたいと思います。<br>※apex:actionPollerについては以前ブログで実験したので今回省きます。→<a href="https://keneloper.com/2020/02/03/try-apex-actionpoller/">こちらです。</a></p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>やってみよう</h3>
<!-- /wp:heading -->

<!-- wp:heading {"level":4} -->
<h4>apex:actionFunction</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>ではまず、apex:actionFunctionからです。いつもの引用でご説明すると、</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>AJAX 要求を使用したコントローラの action メソッドを JavaScript コードから直接呼び出すことをサポートするコンポーネントです。</p><cite><a href="https://developer.salesforce.com/docs/atlas.ja-jp.pages.meta/pages/pages_compref_actionFunction.htm">Visualforce 開発者ガイド:apex:actionFunction</a></cite></blockquote>
<!-- /wp:quote -->

<!-- wp:paragraph -->
<p>JavaScriptからApexコントローラのメソッドを呼び出せるという機能だそうです。<br>下記のようなコードを用意してみました。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>VF</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">&lt;script&gt;
function callAction(){
     callActionFunction();
}
&lt;/script&gt;
&lt;apex:actionFunction action="{!fromActionFunction}" name= "callActionFunction"/&gt;
&lt;input type="button" onclick="callAction();" value="呼び出し"/&gt;</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>Apex</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">public PageReference fromActionFunction(){
    system.debug('呼び出されましたよ〜');
    return null;
}</pre>
<!-- /wp:preformatted -->

<!-- wp:image {"id":1163,"width":76,"height":31,"sizeSlug":"large"} -->
<figure class="wp-block-image size-large is-resized"><img src="https://keneloper.com/wp-content/uploads/2020/02/スクリーンショット-2020-02-08-21.25.56.png" alt="" class="wp-image-1163" width="76" height="31"/><figcaption>ボタンを押すと。。。</figcaption></figure>
<!-- /wp:image -->

<!-- wp:image {"id":1164,"sizeSlug":"large"} -->
<figure class="wp-block-image size-large"><img src="https://keneloper.com/wp-content/uploads/2020/02/スクリーンショット-2020-02-08-21.27.14.png" alt="" class="wp-image-1164"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>ちゃんと表示されました。<br>順序としては、JavaScriptを呼び出す→actionfunction→Apexメソッドって感じですね。</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>apex:actionStatus</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>これはAJAX要求の現在のステータスを表示することができるタブになります。<br>タブが読んで字のごとくでありがたい方です。<br>実際に試してみました。※actionPollerでやったコードに足してみました。</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">&lt;apex:actionStatus startText=" (incrementing…)" stopText=" (done)" id="counterStatus"/&gt;</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>このタブを追加するだけで現在のAJAX状況が参照できます。<br>具体的には処理が始まってから処理中の間はstartTextに設定した文字が、終了もしくは要求のない状態ではstopTextの文字が出てきます。<br>実際の画面ですが、</p>
<!-- /wp:paragraph -->

<!-- wp:video {"id":1169} -->
<figure class="wp-block-video"><video controls src="https://keneloper.com/wp-content/uploads/2020/02/画面収録-2020-02-08-22.23.38.mov"></video></figure>
<!-- /wp:video -->

<!-- wp:paragraph -->
<p>これは他に比べるとユーザに現在の進行状況を表すものになります。</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>apex:actionSupport</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>このタブは他のコンポーネントに対して、AJAX要求のアクションを追加することができるタブです。<br>実際にやってみましょう。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>VF</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">&lt;apex:outputPanel id="Panel"&gt;
    &lt;apex:outputText value="{!hoge}"/&gt;
    &lt;apex:actionSupport action="{!getMessage}" event="onclick" rerender="Panel" status="status"/&gt;
&lt;/apex:outputPanel&gt;</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>Apex</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">hoge = 'テストだよ';

public void getMessage(){
    hoge = '押されたよ';
}</pre>
<!-- /wp:preformatted -->

<!-- wp:image {"id":1175,"width":206,"height":169,"sizeSlug":"large"} -->
<figure class="wp-block-image size-large is-resized"><img src="https://keneloper.com/wp-content/uploads/2020/02/スクリーンショット-2020-02-09-10.10.37.png" alt="" class="wp-image-1175" width="206" height="169"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>こんな感じでパネルをクリックすると変更されます。<br>特定のコンポーネントに対して、処理を入れたい際に使います。</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4>apex:actionRegion</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>このタブが一番理解に苦しみました。<br>このタブにラップされているコンポーネントのみをサーバ側に送信するという動きだそうです。<br>ですので、通常必須項目などがあった場合に、必須項目の選択がない場合、<br>actionを呼び出すと項目エラーがでますが、<br>このコンポーネントを指定してしる場合にはそれを無視して、そのコンポーネントのみを<br>Apex側に渡すことができるようです。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>VF</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">&lt;apex:page controller="sample"&gt;
     &lt;apex:form id="form"&gt;
         &lt;apex:inputField value="{!acc.Name}" required="true"/&gt;
         &lt;apex:inputField value="{!acc.Type}"&gt;[br/&gt;
             &lt;apex:actionSupport event="onchange" action="{!getMessage}" reRender="form"/&gt;
             &lt;/apex:inputField&gt;
         選択されたのは {!hoge} です。[br/&gt;
     &lt;/apex:form&gt;
 &lt;/apex:page&gt;</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>Apex</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">public String hoge{get; set;}
public Account acc {get; set;}

public sample(){
     this.acc = new Account();
     hoge = acc.Type;
}

public void getMessage(){
    system.debug(acc.Name);
    hoge = acc.Type;
}</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>画面をみてみると</p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":1179,"width":250,"height":117,"sizeSlug":"large"} -->
<figure class="wp-block-image size-large is-resized"><img src="https://keneloper.com/wp-content/uploads/2020/02/スクリーンショット-2020-02-09-10.58.25.png" alt="" class="wp-image-1179" width="250" height="117"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>必須項目のNameを指定せずに選択リストを変更するとエラーで返されます。<br>これは裏側で必須項目をチェックした後にApexに送信するものだからだと思われます。</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>では下記のようにapex:actionRegionを追加してやってみます。</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">&lt;apex:page controller="sample"&gt;
     &lt;apex:form id="form"&gt;
         &lt;apex:inputField value="{!acc.Name}" required="true"/&gt;
         <strong>&lt;apex:actionRegion&gt;</strong>
         &lt;apex:inputField value="{!acc.Type}"&gt;[br/&gt;
             &lt;apex:actionSupport event="onchange" action="{!getMessage}" reRender="form"/&gt;
             &lt;/apex:inputField&gt;
         <strong>&lt;/apex:actionRegion&gt;</strong>
         選択されたのは {!hoge} です。[br/&gt;
     &lt;/apex:form&gt;
 &lt;/apex:page&gt;</pre>
<!-- /wp:preformatted -->

<!-- wp:video {"id":1181} -->
<figure class="wp-block-video"><video controls src="https://keneloper.com/wp-content/uploads/2020/02/画面収録-2020-02-09-11.04.26.mov"></video></figure>
<!-- /wp:video -->

<!-- wp:paragraph -->
<p>このように必須項目を無視して<strong>apex:actionRegion</strong>に囲まれている、コンポーネントの値のみ<br>Apex側に送信することができます。<br>条件によって送信するものを変えるなどの実装に使うことができそうですね。</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>まとめ</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>理解をすすめながらやっていくのは難しいですが、<br>実際に作ってみると理解が深まりました。<br>ここのコードは貼り付けて使えるのでぜひ実際に手を動かしてみてください。</p>
<!-- /wp:paragraph -->