[salesforce][AngularJS ] force.comでAngular.jsを覚える
以前からAngular.jsのAngularJS Hello Worldを見た感動をforce.com開発にも適用したいと思ってたんですが、VisualforcePageはHTMLのカスタム属性NGだったので「ダメじゃん」と諦めていました。
しかし先日developerforceにAngularJS and ngForce: More Fun in the Javascript Playgroundという記事が上がったので早速中身を見てforce.comでのAngular.jsの活用方法を整理してみました。
※Angular.jsって?という方はドットインストールさんのこちらの講座が非常に解りやすいですよ。
※この記事に書いてある内容を試す場合は以下のパッケージをインストールしてください。
https://login.salesforce.com/packaging/installPackage.apexp?p0=04tE0000000E9LB
VisualforceでHello!World
なんとAngular.jsで必ず必要な「ng-app」というカスタム属性ですがclass指定でも良いそうです。。。
[html]
<apex:page >
<apex:includeScript value="{!URLFOR($Resource.LABJS_Angular, ‘angular105/angular.min.js’)}" />
<div class="ng-app">
<label>Name:</label>
<input type="text" ng-model="name" placeholder="Enter a name here" />
<hr />
<h1>Hello {{name}}!</h1>
</div>
</apex:page>
[/html]
まあ早い話、HTMLのカスタム属性NGの時点で早々に諦めてクラス属性で指定できる事を探らなかった落ち度です。。。
RemoteTK
さて、あとはAngular.jsのControllerのプロパティにContactなりOpportunityなりをブチ込んでやれば取引先責任者一覧や商談一覧ができるのは想像できると思います。
そこでJavascript Remotingの出番だと思うのですが、このへんを便利にしてくれるRemoteTKというコンポーネントを利用する方向でやっていきたいと思います。
使い方は以下の通り。
[html]
<c:LABJS_RemoteTK />
<script type="text/javascript">
var client = new remotetk.Client();
client.query(queryString, successCallback, errorCallback); //Select
client.create(objectName, fields, successCallback, errorCallback); //Insert
client.update(objectName, objectId, fields, successCallback, errorCallback); //Update
client.del(objectName, objectId, successCallback, errorCallback); //Delete
</script>
[/html]
※上記ソースのobjectNameは対象オブジェクト名、objectIdはUpdateまたはDeleteする対象のオブジェクトID、fieldsはInsertまたはUpdateする値をKey:Valueで渡す、successCallbackは成功時のコールバック関数、errorCallbackは失敗時のコールバック関数です。
RemoteTKコンポーネントを読込んでインスタンス化し各メソッドを実行すればオブジェクトのSelect、Insert、Update、Deleteが可能です。
Angular.js+RemoteTKで取引先責任者一覧
最後にAngular.jsとRemoteTKを組み合わせることで単純にRemoteTKのみ利用する場合よりも少ないコードですっきり実装するようにコーディングします。
[html]
<apex:page >
<apex:includeScript value="{!URLFOR($Resource.LABJS_Angular, ‘angular105/angular.min.js’)}" />
<c:LABJS_RemoteTK />
<script type="text/javascript">
function ContactCtrl($scope) {
$scope.contacts = [];
$scope.refreshContacts = function(newContacts) {
$scope.contacts.length = 0;
$scope.contacts = newContacts;
}
}
var client = new remotetk.Client();
client.query(
‘Select Id, Name, LeadSource, Sortable_Index__c From Contact Order By Sortable_Index__c LIMIT 100’,
function(response) {
e = document.getElementById(‘angularContactList’);
scope = angular.element(e).scope();
scope.$apply(function() {
scope.refreshContacts(response.records);
});
},
function(response) {
alert (‘error!’);
console.log(response);
}
);
</script>
<apex:pageBlock title="Angular+RemoteTKでContact List">
</apex:pageBlock>
<div class="ng-app">
<div id="angularContactList" ng-controller="ContactCtrl" style="width: 50%; float: left;">
<ul>
<li id="{{current.Id}}" ng-repeat="current in contacts" ng-class-even="’rowEven’">{{current.Name}}</li>
</ul>
</div>
</div>
</apex:page>
[/html]
この構成であればApexでControllerを書かなくても、ある程度のアプリケーションを実装できると思います。
さらに今後もAngularJS側のバリデーションやフィルタ、ソートなど便利な機能を最大限利用し、コーディングの量を減らしながらシンプルにスッキリ書く方法を追求します。