エンジニアの谷隈です。
Spring'14からパイロットリリースされている新機能「Visualforce Remote Objects」でのデータ取得について前回検証しました。
今回は更新処理について検証します。
ちなみに「Visualforce Remote Objects」というのはVisualforce上からJavaScript経由でセールスフォース上のオブジェクトデータを操作(取得・作成・更新・削除)する仕組みです。
○使い方
「Visualforce Remote Objects」を使用する際の大まかな手順は次の2ステップになります。
データ更新をする場合でも大まかな手順はデータ取得の場合と同じです。
まずはイメージを掴むための、簡単なサンプルから。
コード例:Visualforce
<apex:remoteObjects > <apex:remoteObjectModel name="Test__c" fields="Id, Name, DateField__c, DateTimeField__c, CreatedDate"/> </apex:remoteObjects>
「Visualforce Remote Objects」でオブジェクトのデータを操作する場合には、どのオブジェクトのどのフィールドを使用するかどうかをapexタグで宣言する必要があります。
上のコードはVisualforceページにTest__cオブジェクトを使用するためのタグを記載したコード例です。
Test__cオブジェクトのId, Name, DateField__c, DateTimeField__c, CreatedDateフィールドへの使用を宣言しています。
apexのタグの使い方はデータ取得の場合と同じです。
apexタグのドキュメントは下記です。
apex:remoteObjects
http://www.salesforce.com/us/developer/docs/pages/Content/pages_compref_remoteObjects.htm
apex:remoteObjectModel
http://www.salesforce.com/us/developer/docs/pages/Content/pages_compref_remoteObjectModel.htm
apex:remoteObjectField
http://www.salesforce.com/us/developer/docs/pages/Content/pages_compref_remoteObjectField.htm
コード例 JavaScript
var obj = new SObjectModel.Test__c(); obj.set('Id', 'a00U0000006eU8fIAE'); obj.set('DateField__c', new Date()); obj.update(function(error, result, event){ // 更新完了後の処理 });
JavaScript側のコードは、apexタグにより生成されたモデルを利用してデータの操作を行います。
データの更新には「update」functionを使用します。
上の例は最も使うであろう呼び出し方で書いていますが、「update」function にはいくつか呼び出し方にバリエーションがあります。
○JavaScriptコードについての詳細
「Visualforce Remote Objects」利用時のJavaScriptコードの基本的な流れは次の2ステップです。
1. apexタグにより生成されたモデルのオブジェクトを生成
2. 生成したオブジェクトのメソッドを呼び出す。
データの更新にはapexタグで生成されたモデルの「update」functionを使います。
Updating Records with Remote Objects
https://www.salesforce.com/us/developer/docs/pages/Content/pages_remote_objects_using_update.htm
パターン① シンプルなupdate
「update」functionの一番シンプルな呼び出し方は、引数無しでfunctionを呼び出すだけの形になります。
var obj = new SObjectModel.Test__c(); obj.set('Id', 'a00U0000006eU8fIAE'); obj.set('DateField__c', new Date()); obj.update();
ドキュメントには上の形の変形パターンとして引数でセットする値をオブジェクトで渡す形の説明がありましたが、実際に試してみたところこちらは正しく動作しませんでした。
何か試し方が悪かったのかもしれません。
var obj = new SObjectModel.Test__c(); obj.update({ Id: 'a00U0000006eU8fIAE', DateField__c: new Date() });
いずれにしろ、シンプルな呼び出しのパターンではupdate処理が成功したかどうかが確認できないので使うケースはあまり無さそうです。
パターン② updateの結果をコールバックfunctionで処理する
「update」functionは引数に実行結果を処理するコールバックfunctionを指定して呼び出すこともできます。
var obj = new SObjectModel.Test__c(); obj.set('Id', 'a00U0000006eU8fIAE'); obj.set('DateField__c', new Date()); obj.update(function(error, result, event){ // 更新完了後の処理 });
使うとしたらこれが一番活躍するパターンだと思われます。
引数にコールバックfunctionを指定します。
更新処理完了後、ここで指定したfunctionが呼び出されるので、処理結果に応じた後処理を行うことができます。
function callback(error, results, event) { // ... }
基本、retrieveの時と同じですが一部格納されるデータに違いがあります。
コールバックfunctionの引数
引数 | 説明 |
---|---|
error | エラーメッセージが格納されます。正常終了時はnullです。 |
results | 更新処理で影響を受けたオブジェクトのIDが配列で返されます。 |
event | DML操作の詳細情報が格納されます。 |
Remote Objects Callback Functions
http://www.salesforce.com/us/developer/docs/pages/Content/pages_remote_objects_callback_functions.htm
パターン③ 複数レコードを一括で更新する
最後は複数レコードを一括で更新する呼び出し方です。
第1引数に更新するオブジェクトのIDの配列、第2引数に更新する値を指定したオブジェクト、第3引数にコールバックfunctionを指定します。
var obj = new SObjectModel.Test__c(); obj.update( ['a00U0000006eU8fIAE','a00U0000006eU8eIAE'] ,{DateField__c: new Date(2020,8,1)} ,function(error, result, event){ // 更新完了後の処理 } );
この一括更新は指定した全オブジェクトを同じ値に更新することしかできないので、使いどころは限られてくると思います。
○その他気になるポイント
・バリデーションエラー
バリデーションエラー発生時の動きは必須項目設定、入力規則、その他の場合、すべて同じです。
コールバックfunctionのerrorオブジェクトにエラーメッセージが設定されて帰ってきます。
function callback(error, results, event) { // ... }
簡易にチェックするならerrorがnullでないかで確認が可能です。
また、同様な情報はeventオブジェクトにも含まれています。
・トランザクション
トランザクションはDML操作のfunction呼び出し単位になります。
トランザクションを考慮した処理を実装したい場合は別の方式を考える必要がありそうです。
Best Practices for Using Remote Objects
https://www.salesforce.com/us/developer/docs/pages/Content/pages_remote_objects_considerations.htm
・オブジェクト権限と項目レベルセキュリティ
オブジェクト権限に読み取りしかない場合、updateの呼び出し結果はエラーになります。
項目レベルセキュリティについては読み取りのみの項目の場合も更新できました。
これは裏側の実装がapexだからということなのかもしれません。
Visualforce Remote Objects
http://www.salesforce.com/us/developer/docs/pages/Content/pages_remote_objects.htm
・日付/日時型の扱い
日付/日時型の値は取得時にはローカルタイムゾーンでDate型に変換されて表示されます。
ここまでは問題ありません。
ところが保存時はJavaScript上のDateの時間がGMT+0000扱いされている様で、SF上で9時間加算されます。
結果、日本環境だと取得してそのまま保存するだけで9時間加算されてしまいます。
今がパイロットだからということであれば良いのですが、修正されない様であれば注意が必要です。
○おまけ
Summer'14のリリースでVisualforce Remote Objectsに機能追加がされる様です。
主な追加機能。
・検索処理時に指定できる条件の追加(lte, gte, ne, order by)
・upsert()操作の追加
・デフォルトの処理のオーバーライドが可能になる
Visualforce Remote Objects Enhancements
https://developer.salesforce.com/releases/release/Summer14/Visualforce+Remote+Objects+Improvements