Salesforceのクライアント側をカスタマイズする際にjQuery, Angular, Backbone…を使った例は沢山見かけるようになったけど、そろそろExt JSを使った例も出て良いかな?ということで、色々試してみたことを記録していきます。
Apexの実装について
クライアント側とのデータ通信では、REST API
or Javascript RemoteAction
(以下、RemoteAction
)のどちらかを使うことになると思います。
ただ、フロント側をVisualforce Page
で実装する場合、APIコール数消費によるエラーを回避する、という点では、RemoteAction
を使う方が良いでしょう。
そんなわけで、ここではRemoteAction
を使う前提にします。
1. RemoteAction
のパラメータについて
Apex上でRemoteAction
を実装する際には、(当然ながら)パラメータを指定する必要がありますが、クライアントサイドからどんなパラメータが渡ってくるか、事前に決めておくのもなかなか億劫な気もします。(苦笑)
というわけで、クライアントサイドからはMapを引数として受け取って、処理するようにしてみました。
// Sample
@RemoteAction
global static Response hogehoge(Map<String, String> param){
Id objectId = param.containsKey('objectId')
? param.get('objectId')
: null;
...
}
引数としてMap<String, String>
を受け取ります。
このMapにどんなキーで値をセットするかは予め決めておく必要がありますが、こうすることで、他のRemoteAction
も引数は同じように定義できます。
※1 クライアントサイドでは、Ext Directを使用する際のConfigを変更すればMapとしてパラメータを渡せます。
※2 もちろん、引数の順番、型を予め指定しておいて、クライアント側から送ることもできるようですので、事前にちゃんと決めておくのも良いかと思います。
2. RemoteAction
のレスポンスについて
先人の知恵をお借りして、レスポンス用のクラスを用意します。
public class Response {
public Boolean success;
public String errorMessage;
public List<SObject> records;
public Integer total;
public Response(){
records = new List<SObject>();
success = true;
total = 0;
errorMessage = '';
}
}
ちなみに、上記の例ではrecords
としてList<SObject>
を定義してますが、List<Object>
とすることもできます。こうしておくと、ユーザー定義型のオブジェクトを返すこともできるので、便利な場合もあります。
(例えば、隣接リスト形式でデータを返したい..など)
3. RemoteAction
の実装
後は、Apex側で処理したいことを実装するのみです。
シンプルな例として、検索条件を受け取って、取引先を検索するRemoteAction
を考えてみましょう。
public with sharing class AccountRemoteActionController {
public AccountRemoteActionController(){}
@RemoteAction
public static Response doSearch(Map<String, String> param){
Response res = new Response();
try{
String accName = param.get('Name');
String accNo = param.get('AccountNumber');
List<Account> accs = [Select Name,AccountNumber
From Account
Where Name = :accName and AccountNumber = :accNo
Order By Name];
res.total = accs.size();
res.records = accs;
}catch(Exception ex){
res.errorMessage = ex.getMessage();
res.success = false;
}
return res;
}
}
【補足】
クライアント側からは、
{
Name: 'AAA',
AccountNumber: 'BBB'
}
といったパラメータを受け取ります。
※キーにName
とAccountNumber
を指定する、というのを決まり事にしています。
上のようなパラメータを受け取って、Apex側で分解します。
String accName = param.get('Name');
String accNo = param.get('AccountNumber');
これを検索条件として、取引先を取得するためのSOQLを発行します。
List<Account> accs = [Select Name,AccountNumber
From Account
Where Name = :accName and AccountNumber = :accNo
Order By Name];
最後に、取得した結果をレスポンス用のオブジェクトにセットして返します。
res.total = accs.size();
res.records = accs;
4. この後
多分、クライアント側..すなわちExt JSによる実装編に続く予定です。