Top Banner
Join the conversation: #forcewebinar ハッシュタグでShareしよう: #forcewebinarjp Force.com Webinar: アドバンスド Visualforce Mitsuhiro Okamoto Program Manager Developer / Platform Marketing
56

Force.com Weibnar : アドバンスドVisualforce

Nov 18, 2014

Download

Technology

Visualforceはカスタムユーザ・インタフェースを作成するのに欠かせないパ­ワフルなツールですが、この大いなる力には、大いなる責任が伴います。作成したページ­が引き締まって快速に動作することは、良いユーザ体験や導入・定着化には非常に重要で­す。このWebinarでは、いくつかの上級者向けのVisualforce機能にト­ピックを置いて、作成するページの効率化を支援します。すでにVisualforce­フレームワークを利用している開発者向けのセッションです。
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

Force.com Webinar:アドバンスド Visualforce

Mitsuhiro OkamotoProgram Manager

Developer / Platform Marketing

Page 2: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

Agenda

1. 前提条件2. 厄介だけどいい友達: View State

3. View Stateの管理4. 非同期Apex

Page 3: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

想定と難易度

Page 4: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

この アドバンスド Webinar の前提条件...

Page 5: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

この アドバンスド Webinar の前提条件...

...不明点なく、自信を持ってVisualforceが記述できる

Page 6: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

この アドバンスド Webinar の前提条件...

...不明点なく、自信を持ってVisualforceが記述できる

...一般的なApexコードを書く事ができる

Page 7: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

この アドバンスド Webinar の前提条件...

...不明点なく、自信を持ってVisualforceが記述できる

...一般的なApexコードを書く事ができる

...HTML & JavaScriptそしてAJAXのコンセプトを理解している

Page 8: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

厄介だけどいい友達:View State

Page 9: Force.com Weibnar : アドバンスドVisualforce

Q: View Stateとは?

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

A: Apexコントローラの状態やVisualforceページの状態をサーバリクエスト間も保持するための、Visualforceページ内に暗号化されたhiddenの <input> フィールドのこと。 このフィールドは

<apex:form> タグがページ上にある場合のみ生成される。

Page 10: Force.com Weibnar : アドバンスドVisualforce

Visualforceのライフサイクル

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

<input type="hidden" value="..."/>

HTTP POST

HTTP GET

A

B

C

D

E

A : URLがリクエストされるB : Apexコントローラがサーバ上でインスタンス化されるC : コントローラの状態がView Stateに直列化(シリアライズ)& 暗号化されてD : ページマークアップがブラウザに送信され、描画されるE : View Stateが復号 & 復元される(PostBack時)

Page 11: Force.com Weibnar : アドバンスドVisualforce

View State: 利点と課題

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

課題 :-(

• 巨大化し、パフォーマンスに影響を与える可能性

• サイズ制限(135k)を持っている

• 複雑なAJAX機能に対応しづらい

すばらしい点 :-)

• 自動的にフィールドの値を保持してくれる

• 簡単なAJAX機能を持ち合わせている

• 非常に簡単に使えるre-renderページコンポーネントを持つ

Page 12: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

View Stateを必要とするもの...

<apex:action*><apex:command*><apex:inlineEditSupport><apex:input*><apex:select*>

Page 13: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

View Stateの管理

Page 14: Force.com Weibnar : アドバンスドVisualforce

どのようにView Stateを管理するか?

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

Page 15: Force.com Weibnar : アドバンスドVisualforce

どのようにView Stateを管理するか?

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

A. コンポーネントの数を減らす

Page 16: Force.com Weibnar : アドバンスドVisualforce

どのようにView Stateを管理するか?

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

A. コンポーネントの数を減らす

B. transient キーワードを利用する

Page 17: Force.com Weibnar : アドバンスドVisualforce

どのようにView Stateを管理するか?

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

A. コンポーネントの数を減らす

B. transient キーワードを利用する

C. JavaScript Remotingを利用する

Page 18: Force.com Weibnar : アドバンスドVisualforce

どのようにView Stateを管理するか?

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

A. コンポーネントの数を減らす

B. transient キーワードを利用する

C. JavaScript Remotingを利用するD. Streaming APIを利用する

Page 19: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション A: コンポーネント数を減らす

Page 20: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション A: コンポーネント数を減らす

<apex:outputPanel layout="inline"...>

<apex:outputPanel layout="block"...>

<apex:panelGrid...>

<apex:outputLink...>

<apex:outputText styleClass="..."...>

Page 21: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション A: コンポーネント数を減らす

<apex:outputPanel layout="inline"...>

<apex:outputPanel layout="block"...>

<apex:panelGrid...>

<apex:outputLink...>

<apex:outputText styleClass="..."...>

<span...>

<div...>

<table...>

<a...>

<span...>

Page 22: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション A: コンポーネント数を減らす

<span...>

<div...>

<table...>

<a...>

<span...>

Page 23: Force.com Weibnar : アドバンスドVisualforce

オプション B: transient キーワード

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

public with sharing class EditClientController {

public Contact client { get; set; } transient public List<Contact> connections { get; set; } transient public List<Account> previousEmployers { get; set; } transient public Set<String> hashTags { get; set; }

...

}

Page 24: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション B: transient キーワードを使う

BEF

OR

EA

FTER

Page 25: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション B: transient キーワードを使う

57%

BEF

OR

EA

FTER

Page 26: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション C: JavaScript Remotingを使うQ: JavaScript Remotingとは?

A: ステートレスにApexコントローラ内のメソッドをJavascriptから呼ぶ方法

Page 27: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション C: Use JavaScript Remoting

取引先責任者を検索:

Page 28: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション C: Use JavaScript Remoting

取引先責任者を検索:

<apex:actionFunction ... /><apex:actionRegion ... /><apex:actionSupport ... />

Page 29: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション C: Use JavaScript Remoting

取引先責任者を検索:

JavaScript Remoting

Page 30: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

JavaScript Remoting のライフサイクル

Page 31: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

JavaScript Remoting のライフサイクル

JS Function

Page 32: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

JavaScript Remoting のライフサイクル

JS Function

Apex Method

Page 33: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

JavaScript Remoting のライフサイクル

JS Function

Apex Method

JS Callback

Page 34: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

JavaScript Remoting のライフサイクル

JS Function

Apex Method

JS Callback

Page 35: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

JavaScript Remoting のライフサイクル

JS Function

Apex Method

JS Callbackクライアントサイド

サーバサイド

Page 36: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

JS Function

Apex Method

JS Callback

Page 37: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション C: JavaScript Remoting: ページ

<apex:page controller="FindCustomerController">

<input id="searchField" type="text" placeholder="姓を入力"/> <button onclick="handleButtonClick();">検索</button> <table> <tbody id="results"></tbody> </table>

</apex:page>

JS Function

Apex Method

JS Callback

Page 38: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション C: JavaScript Remoting: ページ

<apex:page controller="FindCustomerController">

<input id="searchField" type="text" placeholder="姓を入力"/> <button onclick="handleButtonClick();">検索</button> <table> <tbody id="results"></tbody> </table>

</apex:page>

JS Function

Apex Method

JS Callback

Page 39: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション C: JavaScript Remoting: ページ

<apex:page controller="FindCustomerController">

<input id="searchField" type="text" placeholder="姓を入力"/> <button onclick="handleButtonClick();">検索</button> <table> <tbody id="results"></tbody> </table>

</apex:page>

JS Function

Apex Method

JS Callback

Page 40: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション C: JavaScript Remoting: JavaScript

function handleButtonClick() { var searchTerm = document.getElementById("searchField").value; FindCustomerController.doSearch(searchTerm, renderResults);}

JS Function

Apex Method

JS Callback

Page 41: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション C: JavaScript Remoting: JavaScript

function handleButtonClick() { var searchTerm = document.getElementById("searchField").value; FindCustomerController.doSearch(searchTerm, renderResults);}

JS Function

Apex Method

JS Callback

Page 42: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション C: JavaScript Remoting: JavaScript

function handleButtonClick() { var searchTerm = document.getElementById("searchField").value; FindCustomerController.doSearch(searchTerm, renderResults);}

JSコールバック関数ApexメソッドパラメータApexクラス Apexメソッド

JS Function

Apex Method

JS Callback

Page 43: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション C: JavaScript Remoting: Apexクラスpublic with sharing class FindCustomerController {

@RemoteAction public static List<Contact> doSearch(String customerLastName) { customerLastName = '%' + customerLastName + '%'; return [ SELECT id, FirstName, LastName FROM Contact WHERE LastName LIKE :customerLastName LIMIT 200 ]; }

}

JS Function

Apex Method

JS Callback

Page 44: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション C: JavaScript Remoting: Apexクラスpublic with sharing class FindCustomerController {

@RemoteAction public static List<Contact> doSearch(String customerLastName) { customerLastName = '%' + customerLastName + '%'; return [ SELECT id, FirstName, LastName FROM Contact WHERE LastName LIKE :customerLastName LIMIT 200 ]; }

}

JS Function

Apex Method

JS Callback

Page 45: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション C: JavaScript Remoting: コールバック

function renderResults(results, event) { var container = document.getElementById("results"), html = []; for (var i=0, j=results.length; i<j; i++) { html.push("<tr><td>"); html.push(results[i].LastName + ", " + results[i].FirstName); html.push("</td></tr>"); } container.innerHTML = html.join("");}

JS Function

Apex Method

JS Callback

Page 46: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション C: JavaScript Remoting: 結果

JS Function

Apex Method

JS Callback

Page 47: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション C: JavaScript Remoting: 結果

440ms 215msBEFORE AFTER

Page 48: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション C: JavaScript Remoting: 結果

440ms 215ms52%

BEFORE AFTER

Page 49: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション D: Streaming APIを使うQ: Streaming APIとは?

A: Salesforceインスタンスからポーリングをせずにほぼリアルタイムに更新を効率よく取得する方法

Page 50: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション D: Streaming APIを使う

<apex:page controller="NewAccountsController"><apex:form>

<apex:actionPoller action="{!find}" rerender="wrapper" interval="15"/> <h1>Streaming API サンプル</h1> <h2>新規取引先</h2> <apex:outputPanel id="wrapper"></apex:outputPanel>

</apex:form></apex:page>

BEFORE

Page 51: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション D: Streaming APIを使う

<apex:page controller="NewAccountsController">

<apex:includeScript value="..."/> <!-- 4つの js ファイルを読み込み -->

<h1>Streaming API サンプル</h1> <h2>新規取引先</h2> <div id="wrapper"></div> <script>... $.cometd.init(...) $.cometd.subscribe(...) ...</script>

</apex:page>

AFTER

Page 52: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

オプション D: Streaming APIを使う: 手順SOQLクエリを定義するPushTopicレコードを定義するVisualforceページに必要なJavascriptをインクルードするcometdのinit(...)およびsubscribe(...)を呼び出す (Inline JS)

何が起きるかを見る

Page 53: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

非同期 Apex

Page 54: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

非同期 Apexpublic with sharing class SendInvoiceController{

@RemoteAction public static String requestAllInvoices(String customerId) { sendAllInvoices(customerId); return('All invoices have been requested.'); }

@future private static void sendAllInvoices(String customerId) { EmailHelper.emailCustomerInvoices(customerId); }

}

Page 55: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

Q & A

Mitsuhiro OkamotoProgram Manager

Developer / Platform Marketing

Page 56: Force.com Weibnar : アドバンスドVisualforce

Join the conversation: #forcewebinarハッシュタグでShareしよう: #forcewebinarjp

Thank you