画面上からぽちぽち静的リソースアップロードするのつらすぎ
やること
- CLIから静的リソースのアップロード
はじめに
jsforceという神ライブラリ使います
いつも大変お世話になっております
jsforce-metadata-tools
まだの人はコマンド使えるようにインストールしといてください
1. デプロイ環境整備 & リソース用意
用意する環境はこんな感じ
$ tree
.
├── assets
│ └── js
│ └── hoge.js
└── package
├── package.xml
└── staticresources
├── hoge.resource
└── hoge.resource-meta.xml
前回のやつ のJSを切り出す
function sayHello(helloTo) {
new Promise((resolve, reject) => {
Visualforce.remoting.Manager.invokeAction(
'{!$RemoteAction.SR_Controller.sayHello}',
helloTo,
function(result, event) {
if(event.status) {
resolve(result);
}
}
);
})
.then(function(data) {
document.getElementById("main").innerHTML = data;
});
return false;
}
圧縮
$ zip package/staticresources/hoge.resource assets/js/hoge.js
「hoge」の部分がNameになるのであまり適当なものをつけないほうがいいかも
拡張子は.resourceじゃないとデプロイした時に怒られる
最小限のpackage.xml用意
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>hoge</members>
<name>StaticResource</name>
</types>
<version>40.0</version>
</Package>
リソース(hoge.resource)に付随するxmlが無いと怒られるので作成
<?xml version="1.0" encoding="UTF-8"?>
<StaticResource xmlns="http://soap.sforce.com/2006/04/metadata">
<cacheControl>Public</cacheControl>
<contentType>application/zip</contentType>
</StaticResource>
XMLの書き方はここ
メタデータ API 開発者ガイド - StaticResource
2. デプロイ
下記コマンドで一発デプロイ。神ライブラリすぎます!!!!!!
$ jsforce-deploy -u {username} -p {password} -D ./package/
Logged in as: ***********
Deploying to server...
Deploy Succeeded.
sandboxならlオプションでログインURL指定できます。
3. 確認
前回のやつ とおんなじ感じでファイルを用意
<apex:page showHeader="false" sidebar="false" controller="SR_Controller">
<div id="main">
<input type="button" onClick="sayHello('Marc')" value="Salesforceへのリンク"/>
</div>
<script type="text/javascript" src="{!URLFOR($Resource.hoge, '/assets/js/hoge.js')}"></script>
</apex:page>
public with sharing class SR_Controller {
@RemoteAction
public static String sayHello(String helloTo) {
return 'Hello ' + helloTo;
}
}
で前回と同じようにRemoteActionできるはず、ができない。。。
余談:RemoteAction周りでちょっと詰まった話
コンソールにエラーが吐かれてるので確認すると、
VFRemote.js:121 Uncaught (in promise) TypeError: Cannot read property 'SR_Controller' of undefined
at Object.getObject (VFRemote.js:121)
at constructor.getController (VFRemote.js:137)
at constructor.getAction (VFRemote.js:137)
at constructor.invokeAction (VFRemote.js:138)
at Promise (hoge.js:3)
at new Promise (<anonymous>)
at sayHello (hoge.js:2)
at HTMLInputElement.onclick (sr:8)
で、VFRemote.jsのgetObjectの引数みてみたら
VFRemote.js:122 {!$RemoteAction.SR_Controller
VFRemote.js:123 undefined
VFRemote.jsを少し読み進めると
getAction: function(a) {
if (!a || !$VFRM.Util.isString(a) || -1 == a.indexOf(".")) return null;
var b = this.getController(a.substring(0, a.lastIndexOf("."))),
? ?
a.substring(0, a.lastIndexOf("."))),
ここにきてVFの記法を思い出した、外部リソースはコンパイルされないのね
function sayHello(helloTo) {
new Promise((resolve, reject) => {
Visualforce.remoting.Manager.invokeAction(
'{!$RemoteAction.SR_Controller.sayHello}', // ←ココ
helloTo,
function(result, event) {
if(event.status) {
resolve(result);
}
}
);
})
.then(function(data) {
document.getElementById("main").innerHTML = data;
});
return false;
}
:'{!$RemoteAction.SR_Controller.sayHello}'
:'SR_Controller.sayHello'
ちゃんと動きました
外部JSからのRemoteActionの参照はそのままテキストで渡せば(おそらく)OK
なにが入ってんのかなーと思い{!$RemoteAction}をVFのページに直書きしてみると
無効なグローバル変数「ApexPagesELAdapterContext.$RemoteAction」を使用しています。期待される項目セレクタがありません。
見たい、中身知ってる人(見方分かる人)いたら教えてください。
公式docっぽいの見てみたけど、VFに直接記述しない場合は自動で名前解決されないのでコントローラとメソッドだけでOKってことで良いのかな。
名前空間および JavaScript Remoting
おわり。