こんにちは、管理人の@Salesforce.Zです。
apex:commandButtonタグのreRender属性に問題があった。。。
問題概要を言いますと、ボタンをクリックによって、画面の部分更新をしたくて、reRender属性で対応しようと思い、
しかし、Not working。。。。。。、なんだと。。。と思ったけど、
★ apex:commandButtonのreRenderが動作しない対策
目次
画面再描画機能
sfdcのVFを構成するタグが多数あり、ほとんど、reRender属性があります
画面の一部を更新するには非情報に便利な属性である
普段のパタン
コントロールクラスを用意し、画面表に応じて、DTOクラスをクラス内部で宣言し充分、
この例では、画面にテーブルを表示し、テーブルの上にある「行追加」ボタンを押下することによって
一行がテーブルに追加され、テーブルの領域のみ再描画する
次のサンプルで、対応し、十分に実現可能だが、コンポーネントでいろいろ表示しまくる時に動作しない部分がある
サンプルコントロールApexクラス
public with sharing class YourController { public List<displayDTO> dtoList {get;set;} public YourController(){ dtoList = new List<displayDTO>(); } pulic Pagereference addRow(){ displayDTO row = new displayDTO(); row.rowNo = 1; if(!dtoList.isEmpty()){ row.rowNo = dtoList.size() + 1; } return null; } /** * 編集リンク */ public Pagereference EditLink(){ return null; } /** * 削除リンク */ public Pagereference DeleteLink(){ return null; } public class displayDTO { public Account acc {get;set;} public Integer rowNo {get;set;} // コンストラクタ public displayDTO() { this.acc = new Account(); this.rowNo = 0; } } }
サンプルコントロールApexクラスがコントロールするVF画面
<apex:page controller="YourController" tabStyle="Account"> <apex:form id="pageid"> <apex:pageBlock> <apex:pageBlockSection columns="1"> <apex:commandButton value="行追加" action="{!addRow}" reRender="edit_tbl"/> <apex:pageBlockTable value="{!dtoList}" var="dto" id="edit_tbl"> <apex:column id="col_link_btn"> <apex:commandLink action="{!EditLink}" value="編集" id="row_edit_id" reRender="edit_tbl"> <apex:param name="editIdx" value="{!dto.rowNo}" /> </apex:commandLink> <apex:outputText value=" | "/> <apex:commandLink action="{!DeleteLink}" value="削除" id="row_del_id" reRender="edit_tbl"> <apex:param name="delIdx" value="{!dto.rowNo}" /> </apex:commandLink> </apex:column> <apex:column value="{!dto.acc.Name}" /> <apex:column value="{!dto.acc.好きな列}" /> </apex:pageBlockTable> </apex:pageBlockSection> </apex:pageBlock> </apex:form </apex:page>
テーブルの部分をコンポーネントにし、親ページに入れ子として表示、問題点と対策
なぜ、コンポーネントにするかというと、コンポーネントの部分を繰り返し、画面の違う部分に表示する必要がある場合とか、コードをページ上で、コピペも良いが、格好悪いね?効率も悪いし
ほんで、コンポーネントにしたわけ
すると、ボタンが再描画は動作しません
理由は分かりません🙇🙇🙇 💦💦💦
問題点
問題点は2つあった
・ボタンの再描画機能しません
・内部クラスDTOは使えません
対策
・ボタンのアクションをコンポーネントにパスして、コンポーネント内にアクションを受け取って、再描画する
・DTOをクラスの内部から、外部にする
コントローラークラス
public with sharing class YourController { public List<displayDTO> dtoList {get;set;} public YourController(){ dtoList = new List<displayDTO>(); } pulic Pagereference addRow(){ displayDTO row = new displayDTO(); row.rowNo = 1; if(!dtoList.isEmpty()){ row.rowNo = dtoList.size() + 1; } return null; } /** * 編集リンク */ public Pagereference EditLink(){ return null; } /** * 削除リンク */ public Pagereference DeleteLink(){ return null; } }
クラスの内部DTOクラスを外部にする
public with sharing class displayDTO { public Account acc {get;set;} public Integer rowNo {get;set;} // コンストラクタ public displayDTO() { this.acc = new Account(); this.rowNo = 0; } }
最終的なページ側抜粋
<apex:page controller="YourController" tabStyle="Account"> <apex:form id="pageid"> <apex:pageBlock> <apex:pageBlockSection columns="1"> <c:your_componentname dtoList="{!dtoList}" func="{!addRow}"/> </apex:pageBlockSection> </apex:pageBlock> </apex:form </apex:page>
<apex:component controller="YourController" selfClosing="true"> <apex:attribute name="dtoList" description="一覧情報" type="displayDTO[]" /> <apex:attribute name="func" description="テスト" type="ApexPages.Action" /> <apex:pageBlockSection columns="1"> <apex:commandButton value="行追加" action="{!func}" reRender="edit_tbl"/> <apex:pageBlockTable value="{!dtoList}" var="dto" id="edit_tbl"> <apex:column id="col_link_btn"> <apex:commandLink action="{!EditLink}" value="編集" id="row_edit_id" reRender="edit_tbl"> <apex:param name="editIdx" value="{!dto.rowNo}" /> </apex:commandLink> <apex:outputText value=" | "/> <apex:commandLink action="{!DeleteLink}" value="削除" id="row_del_id" reRender="edit_tbl"> <apex:param name="delIdx" value="{!dto.rowNo}" /> </apex:commandLink> </apex:column> <apex:column value="{!dto.acc.Name}" /> <apex:column value="{!dto.acc.好きな列}" /> </apex:pageBlockTable> </apex:pageBlockSection> </apex:component>
終わりに
コンポーネント内で、直接、クラスのアクション(行追加)にする場合、再描画機能が動作しません、メソッド自体はコールされるだけ
あくまでも今回、自分があった問題です。ご参考までに
ほかのサイトでは、actionFunctionを使い、ってような進め方もある
または再描画したい時にコールするメソッドのreturn ApexPages.currentPage()をreturn nullにするとか
いろんなケースで動作しない可能性がある
<apex:actionRegion>タグで対象タグを囲んで、対応するとか、で解決するパターンもある