JavaScript

Force.comとSencha Touchを使ったモバイルアプリケーション開発 Part1

こんにちは、ゼノフィkotsutsumiです。

この記事は、US Sencha社ブログ “Developing Mobile Applications with Force.com and Sencha Touch – Part 1″を翻訳したものです。

概要

既に、Force.comかSencha 開発者であれば、フレームワークを使ったアプリケーション開発の効率を理解していることでしょう。 経験から、どのように作るのか、どのような機能が備わっているのか、コンフィグオプションを記述しながら、いかに迅速にビジネスソリューションを作っていくのかを理解しているはずです。 しかし、複数のフレームワークと合わせた開発は、さらに開発効率を向上させることでしょう。 Sencha TouchとForce.comを一緒に使った、モバイルアプリケーション開発は、その良い例です。そして、Force.comベースのアプリケーションをタッチデバイスで動作させることができるようになります。

一連の記事は、JavaScript、HTML、CSSで、Sencha TouchとForce.comを利用したHTML5アプリケーション開発の方法までカバーします。 Sencha Touch は、非常に簡単にVisualforceとForce.comプラットフォームと一緒に使うことができます。 そして、Salesforce、またはForce.comバックエンドと繋がった強力なビジネスアプリケーションを比較的簡単に作り出すことができます。 ブラウザは、HTML Document Object Model(DOM)を操作することによって、タッチスタイルUIを描画することに優れている。 Snehca Touch アプリケーションは、高度なクラスシステムと、UIコンポーネントライブラリ、そしてMVCパッケージがJavaScriptだけで実装されています。

Sencha Touch アプリケーションは、ホームページ上にHTMLで記述される。そして、すべてのエレメントとコンポーネントのタッチスタイルUIはJavaScriptによって生成されます。フレームワークは、一貫性と予測しやすい構造を提供します。 このオブジェクト指向フレームワークは、クラスを定義、生成、継承、強力なデータ管理機能、モダンタッチスタイルUIを提供します。 Visualforce のページは、HTML コンテンツを配置することができるので、 同様にSencha Touchアプリケーションを配置することも簡単です。


リッチなJavaScriptフレームワーク

Sencha Touchフレームワークは、UIコントロールと300を越えるアイコン、テーマ、MVC、データバインディングなどをサポートします。 ハードウェアアクセラレーションを利用するように設計されており、iOSとAndroidに対して、ネイティブデバイスAPIが利用できるネイティブパッケージャーを含んでいます。 オンラインドキュメントやスクリーンキャスト、他の学習リソースやサンプルなど、アプリケーションを開発するときに必要なものが一通りそろっています。

Sencha Touchは、ピュアJavaScriptで実装されており、最小構成のHTML上でアプリケーションを構築します。 開発者は、JavaScriptに関する深い知識を持っていた方がよいでしょう。 それでも、Sencha Touchの最大の利点は、開発とメンテナンスを簡単にするために、クラスシステムが提供されていることです。これは、JavaScriptの学習にかかるコストを抑制します。

Sencha Touchは、コンポーネントモデルによる構築や、最適化されたコードが利用できるので、企業向けモバイルアプリケーションに非常に適しています。 これらの仕組みが、アプリケーションが成長していく中で、共同開発が可能な状態を維持してくれます。

Sencha Touchは、Visualforceに対して素のJavaScript、または、アプリケーション構築に必要なモジュールをデプロイすることができます。 Senchaライブラリは、クラウドサーバーに配置可能です。 または、Sencha SDK Builder Toolsで、アプリケーション用に高圧縮か最適化されたJavaScriptファイルにミニファイし、Force.comの静的リソースとしてデプロイすることが簡単にできます。 Sencha は、パッチとアップデートをスマートで効率的な方法で行うためのメカニズムを提供します。 Sencha MVC データパッケージは、非常にスケーラブルで持続可能なデータ転送メカニズムとして、Apex controller @RemoteAction メソッド、ならびにForce.com REST APIを利用することができます。


何か簡単なものを構築して、複雑なものへと発展させましょう

フレームワークを理解するために、Sencha Touch と Visualforce を使った簡単なモバイルアプリケーションを構築していきます。 このアプリケーションは、ユーザー認証は実装しません、なぜなら携帯電話のブラウザから直接Salesforceへログインすることができるからです。 Sencha SDK や ツールをダウンロードしてインストールしなくても構いません。開発するアプリケーションは、すべてクラウド上で実行されるからです。

このアプリケーションは、モバイルウェブアプリケーションとして必要な情報を表示するのに1つのページ構成されます。 このアプリケーション名をPocketCRMとしましょう。 何度か繰り返しながら、このアプリケーションをゆっくり構築していきます。 まず、最初にForce.comやウェブサービスからデータをとってくるのではなく、JSONで記述した仮データで構築していきます。 動作を確認したら、仮データのJSONをSalesforceからApex controller メソッドで読み込む方法を学びましょう。 そして、単体テストがコントローラークラス含まれるようにします。 Apex が予想通り動作しているか、データストアに結びつける前に確認します。コードカバレッジをクラスに提供することが、Force.comへ提供する条件です。

フォローアップの記事で、アプリケーションを継承して、読み込みについて掘り下げます。そしてCreate, Read, Update, Delete (CRUD) とクライアント側のバリデーション機能、サーバー側のデータへ、データプロキシを利用し、Apex コントローラーで@RemoteAction メソッドへ接続します。

ローカルのVisualforce Component環境で、これらを繰り返しながら、Sencha Touchアプリケーションによる、MVCのファイルとフォルダ構成を体験することができるでしょう。 Force.com の静的キャッシュリソースとして、最適化とミニファイされたJavaScriptファイルを配信することができます。


さぁ、はじめよう

まず最初に、Sencha Touchフレームワークの一般的な理解と、体系化されたクラスシステム、MVCモデルの便利さを学びましょう。 タッチスタイルインターフェースでも、デスクトップでSafari(Webkit)を利用して開発を進めることができます。 また、 Sencha.io クラウド(Chromeはできないかもしれない)上のJavaScriptとCSSをセキュアでは無い状態で取得することができます。

最初から最後まで、Force.com上でのSencha Touch アプリケーションは、次の4つのSalesforceメタデータが含まれます。

  1. JavaScriptをVisualforceコンポーネントに入れる。
  2. CSSをVisualforceコンポーネントに入れる。
  3. Visualforceページにアプリケーションコンポーネントを配置する
  4. Apex コントローラークラスでデータプロセスを管理する。

ステップ 1: Force.comを使った開発環境の準備

既に、登録済みでSalesforce.comを利用することができ、Force.com Developer Portalを見ることができるなら、Developer Editionを無料で入手できます。 また未登録なら、Join Nowをクリックして、あなたの情報を入力してアカウントを作成してください、追ってメールでログイン方法が送付されてきます。

Force.comについて、何も知らなければ、基本から慣れていってくれることが望ましいです。 たくさんの資料の中からGetting Startedを見ることができます。 Workbook tutorialsを使って、特にForce.com WorkbookとVisualforce Workbookを通すことが、理解の近道です。

セットアップメニューの Develop -> Pages と Develop -> Components エディターから開発を始めることができます。または、開発コンソールからも可能です。 もし、Force.com IDEとEclipseを知っているのであれば、そちらを使っても構いません。 Force.comの開発環境が整ったら次へ進みましょう。


ステップ 2: Sencha Touchライブラリ

どんな新しいプラットフォームやフレームワークを使い始める時でも、まずローカル開発環境を作るところから始めます。 しかし、Force.com Cloud上で開発をしていると、Sencha.io CloudからSencha Touchライブラリを参照することができるので、何も気にすることはない。 後で、ツールとライブラリをダウンロードしてローカル開発環境を構築したくなるかもしれない。そして、Sencha ライブラリのバージョンを固定にしてSalesforceで利用することになるでしょう。 しかし、当面の間は、Web上のライブラリを参照することにする。


ステップ 3: Visualforceのカスタムコンポーネントを使ったJavaScriptアプリケーション構築

Visualforce PageにJavaScriptアプリケーションをカスタムVisualforceコンポーネントとして配置します。 Force.com エディターを起動して、Visualforceコンポーネントを作成してください。 PocketCRM_Appという名前をつけて、JavaScriptコードを含む、<apex:component> と <script> タグ、そして{}と()の整合性に気をつけながら以下のコードと入れ替えてください。

<apex:component >
<script type="text/javascript">
 
//===============================================================================
//APPLICATION
//The Application class is the entry point into your Sencha Touch application.
//===============================================================================
Ext.application({name: "PocketCRM",
//The application's startup routine once all components are loaded.
  launch: function () {
 
    //Instantiate your main list view for Leads.
    var mainView = Ext.create('Ext.Panel', {
      fullscreen: true,
      html: 'Welcome to PocketCRM!'
    });
 
    //Launch the primary fullscreen view and pass in the main view.
    Ext.Viewport.add([mainView]);
 
  }
});
 
</script>
</apex:component>

このJavaScriptコンポーネントが、モバイルアプリケーションのエントリーポイントになります。 簡素なHTML上に、Sencha Touchのパネルコンポーネントを表示するために、具体的なプロパティを含んだものです。 そして、 アプリケーションのビューポート(アプリケーションUIコンテナー)が読み込まれます。 ここまでで、コンポーネントが追加されましたが、最初は空っぽのアプリケーションです。


ステップ 4: Visualforceページにページを作る

私たちは、カスタムVisualforceコンポーネントを含むVisualforce ページを作成するつもりです。 エディタを立ち上げて、 新しいVisualforce ページを作成して、それにPocketCRMをつけて、以下のコードと入れ替えてください。

<apex:page docType="html-5.0" showHeader="false" standardStylesheets="false" cache="false"  >
<head>
<meta charset="UTF-8" />
<title>Pocket CRM</title>
<script src="http://cdn.sencha.io/try/touch/2.0.1/sencha-touch-all.js" />
<link rel="stylesheet" href="http://cdn.sencha.io/try/touch/2.0.1/resources/css/sencha-touch.css"/> 
<!-- Our custom Visualforce component containing our Sencha Touch application -->
<c:PocketCRM_App />
</head> 
<body>
  <!-- An animated image that displays while loading -->  
<div id="appLoadingIndicator">
   <div></div>
     <div></div>
   <div></div>
  </div>
</body>
</apex:page>

ページには、何もありません。 注意として、doctype=”html-5.0″がにあることに注意してください。これについては、Sencha Touch ライブラリのウェブサイトを参照してください。 また、JavaScriputアプリケーションを含むカスタムVisualforceコンポーネントを参照します。 appLoadingIndicatorはアニメーションアイコンとしてアプリケーションにロードされるフレームワークによって提供される画像です。

次のように、Visualforceページの名前をブラウザーのURLアドレスバーに入力することで、何か表示されるはずです。 (Salesforce サーバーインスタンスに依存します)

“Enter”を押すと、サーバーはVisualfoceページを表示するためにリダイレクトをします。(これも、サーバーに依存します)

ページとコンポーネントが正常に作成されれば、Sencha Touchライブラリは、次のように表示を行うはずです。

うまく表示されましたか? Force.com クラウド上でSencha Touch アプリケーションを動作させることができました。 もし、うまく表示されない場合は、Sencha Touch ライブラリのパス、ページやコンポーネントのコードが正しいか、からチェックをしてみてください。 ブラウザでJavaScriptをデバッグする時、多くのクライアントツールが利用できます。


ステップ 5: Visualforceでスタイルを設定する

次に、Sencha Touch アプリケーションスタイルを含むカスタムVisualforceコンポーネントを追加します。 通常、CSSは、CSSファイルを別の静的リソースとして管理します。 しかし、Force.com開発環境内で直接修正する方が簡単なので、この方法をオススメします。 これらは、リリース時にリファクタリングでCSSファイルにすることができます。

そして、PocketCRM_Cssという名前のVisualforceコンポーネントを作って、次のように記述します。


<apex:component >
<style type="text/css">
 
 /**
 * Example of an initial loading indicator.
 * It is recommended to keep this as minimal as possible to provide instant feedback
 * while other resources are still being loaded for the first time
 */
 
html, body {
  height: 100%;
  background-color: #1985D0
}
 
#appLoadingIndicator {
  position: absolute;
  top: 50%;
  margin-top: -15px;
  text-align: center;
  width: 100%;
  height: 30px;
  -webkit-animation-name: appLoadingIndicator;
  -webkit-animation-duration: 0.5s;
  -webkit-animation-iteration-count: infinite;
  -webkit-animation-direction: linear;
}
 
#appLoadingIndicator > * {
background-color: #FFFFFF;
  display: inline-block;
  height: 30px;
  -webkit-border-radius: 15px;
  margin: 0 5px;
  width: 30px;
  opacity: 0.8;
}
 
@-webkit-keyframes appLoadingIndicator{
0% {
  opacity: 0.8
}
 
  50% {
    opacity: 0
  }
 
  100% {
    opacity: 0.8
  }
}
 
 /**
 * PocketCRM Custom styles
 */
 
.x-title{
   min-width:100%
}
 
 /* Increase height of list item so title and narrative lines fit */
.x-list .x-list-item .x-list-item-label
{
  min-height: 3.5em!important;
}
 
/* Move up the disclosure button to account for the list item height increase */
.x-list .x-list-disclosure 
{
  position: absolute;
  bottom: 0.85em;
  right: 0.44em;
}
 
.list-item-line-1
{
  float:left;
  width:100%;
  font-size:90%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding-right:25px;
  line-height:150%;
}
 
.list-item-line-2
{
  float:left;
  width:95%;
  color:#666666;
  font-size:80%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding-right:25px;
}
 
.x-item-selected .list-item-name
{
  color:#ffffff;
}
 
.x-item-selected .list-item-email
{
  color:#ffffff;
}
 
.leads-list-empty-text
{
  padding:10px;
}
 
</style>
</apex:component>

このカスタムスタイルをサポートします。 一般的に使われるSencha Touchコンポーネント用のJavaScript読み込みのアニメーションだけでなく、設定しているCSSをよく知らなくても、心配する必要はありません。 .x-list, .x-list-item と .x-list-item-label のようなSencha側で用意されているクラスを利用していることに注意してください。 Sencha Touchは、アプリケーションにテーマエンジンを提供しています。Sass (Syntactically Awesome StyleSheets)については、後ほど調べてみてください。

PocketCRM_Appに、下記の参照を追加してください。

...
 
    <c:PocketCRM_Css />
    <c:PocketCRM_App />
 
</head>

もう一度ページを表示して、正しく表示されることを確認してください。 見た目は変わりません。


ステップ 6: Sencha Touch アプリケーションの構築

空っぽのアプリケーションを作り、簡単に確認することができました。1度に1つのJavaScriptコンポーネントで作成しましょう。 インタラクティブでインクリメンタルなアジャイルスタイル開発で進めます。

私たちは、これまでのコードに変更を加えていきます。 このように、既に動いているアプリケーションを修正して、素早くテストすることができる。 JavaScriptで、テスト駆動開発ができますが、本稿の範囲外になりますので割愛します。


データストアの追加

まず、最初にアプリケーションに、Senchaデータパッケージ、データローディング管理を行う機構であるデータストアを追加します。 ストアのコレクションは、データベースそのもので、スキーマは、定義済みのモデルクラスに依存します。 今回の場合、Salesforce.com 読み込み標準オブジェクトと、利用できるフィールドのサブセットから始めましょう。

まず最初に、静的なJSONデータを含むストアを作り、認証とデータ転送機能に集中します。

PocketCRM_Appを構成するコンポーネントに次のコードを追加します。(Ext.applicationのコードブロックに、ただJavaScriptを追加するだけです。)

//===============================================================================
//STORES
//Stored serve as the client-side cache of your data; they loading data into your app's views. 
//===============================================================================
//The Lead Store, this version will simply load with mock JSON data.
Ext.define("PocketCRM.store.Leads", {
  extend: "Ext.data.Store",
  requires: "Ext.data.proxy.LocalStorage",
 
  config: {
 
    model: "PocketCRM.model.Lead",
 
    //You can type the following Apex code in the Execute Anonymous window to 
//generate JSON which can then be cut and paste in the component. You can  
    //use the Eclipse Force.com IDE Schema Browser or the Workbench to build SOQL
    //
// List<Lead> leadList = 
//  [SELECT FirstName,LastName,Company,Title,Phone,Email,Status FROM Lead]; 
    //  
    // system.debug(JSON.serializePretty(leadList));
    //
    // While you can easily remove the 'attributes' node, it will be ignored.
 
data: [
    {
      "attributes" : {
        "type" : "Lead",
    "url" : "/services/data/v25.0/sobjects/Lead/00QA0000004wQTZMA2"
      },
    "FirstName" : "Bertha",
    "LastName" : "Boxer",
    "Company" : "Farmers Coop. of Florida",
    "Title" : "Director of Vendor Relations",
    "Phone" : "(850) 644-4200",
    "Email" : "bertha@fcof.net",
    "Status" : "Working - Contacted"
    }, {
      "attributes" : {
        "type" : "Lead",
        "url" : "/services/data/v25.0/sobjects/Lead/00QA0000004wQTaMAM"
      },
      "FirstName" : "Phyllis",
      "LastName" : "Cotton",
      "Company" : "Abbott Insurance",
      "Title" : "CFO",
      "Phone" : "(703) 757-1000",
      "Email" : "pcotton@abbottins.net",
      "Status" : "Open - Not Contacted"
    }, {
      "attributes" : {
        "type" : "Lead",
        "url" : "/services/data/v25.0/sobjects/Lead/00QA0000004wQTbMAM"
      },
      "FirstName" : "Jeff",
      "LastName" : "Glimpse",
      "Company" : "Jackson Controls",
      "Title" : "SVP, Procurement",
      "Phone" : "886-2-25474189",
      "Email" : "jeffg@jackson.com",
      "Status" : "Open - Not Contacted"
    }
    ],
 
    //Create a grouping; be certain to use a field with content or you'll get errors!
    groupField: 'Status',
    groupDir: 'ASC',
 
    //Create additional sorts for within the Group.
    sorters: [
      { property: 'LastName', direction: 'ASC'}, 
{ property: 'FirstName', direction: 'ASC'}
]   
  } 
});

コードを追加したら、Visualforce ページを更新して、正しく表示されることを確認してください。 見た目には何の変化もありませんがJavaScriptエラーがないことを確認してください。

PocketCRM.store.Leadsコンポーネントの命名規則コードをみてください。 この命名規則は、フレームワークのクラス構造を表します。 Senchaは、名前空間(アプリケーション名)と色々なコンポーネントレイヤー(ストア、モデル、ビューなど)を利用しています。最後にコンポーネントそのものの名前を追加します。

ローカルでSencha Touchアプリケーションを開発するとき、この階層構造がファイルとフォルダの関係になります。 今後の記事でも、しっかりこの構造に従った開発方法を説明していきます。 今のところ、コンポーネントをアプリケーションに加えるとき、何度もこの命名規則を目にすることになりますので、注意深くこの構造を見てください。

データモデルの追加

Salesforce データオブジェクトの詳細とスキーマをモデルとして定義します。 モデルは、アプリケーションで利用するデータ構造を表します。 作成中のCRMモバイルアプリケーションの場合、Lead、Contact、Accountになります。あるいは、ユーザーと組織の情報でも良いでしょう。 モデルは主に、フィールドのコネクションとして、オブジェクトのスキーマになります。しかし、さらに洗練された機能があります。

以下のコードを追加してください。 ストアの上にモデルのコードを配置したいが、順番は重要なことではありません。(Sencha Touchの利点の1つです)

//===============================================================================  
//MODELS
//Models are the objects on your application.
//===============================================================================  
 
//The Lead model will include whatever fields are necssary to manage.
Ext.define("PocketCRM.model.Lead", {
  extend: "Ext.data.Model",
 
  config: {
 
    idProperty: 'id',
    fields: [
    { name: 'id', type: 'string'},
    { name: 'FirstName', type: 'string', required: true  },
      { name: 'LastName', type: 'string', required: true  },
      { name: 'Company', type: 'string' },
      { name: 'Title', type: 'string' },
      { name: 'Phone', type: 'string', required: true  },
      { name: 'Email', type: 'string', required: true  },
 
//Although Status is a bonafide field on the Lead object, we want to insure 
                //there is a value as our grouping on this field requires it not be null.
                { name: 'Status', 
                        convert: function(value, record) {
                                    var st = record.get('Status');
                                    return st ? st : "No Status Assigned";
                              }
        },
 
      //This is a derived field using an anonymous 'convert' 
//anonymous function to calculate a string value.
      { name: 'FullName',
convert: function(value, record) {
          var fn = record.get('FirstName');
                var ln = record.get('LastName');
                return fn + " " + ln;
         }
},          
 
  ],
  },
});

モデルの命名規則と、フィールド配列の内容に注意しながら、PocketCRM.model.Leadを作成します。

値がnullの時のためにconvert()関数を利用します。 なぜなら、一覧にnull値を含んではいけないからです。 Force.comにデータを作成することができました。しかし、クライアント再度のバリデーション機能が追加されていません。 そして、それは結構簡単です。

次回、編集可能ビュー作成の時、フィールドレコードのIDを確認する プロパティにも注意してください。

もう一度、コードに追加して、Visualforceページを更新してください。 正しく表示されることを確認したら次へ進みましょう。


リストビュー用コントローラー追加

ユーザーインタフェースが表示される前にインスタンス化される、Leads用のコントローラーを作成します。 Leadオブジェクトのモデルコンポーネントと、Salesforceからデータを取得 (JSONによる仮データ)するストアコンポーネントを作成します。 そして、View(ユーザーインタフェース)のためにクライアントサイドのコントローラーを作る必要があります。そして、ストアからモデル(データ)を提供します。 ビューでユーザーイベントが、発生したときの制御を行います。

ここから先、Model-View-Controller (MVC) について理解している必要があります。 どのようなカスタムForce.comアプリケーションでも、一般的にVisualforceページがViewになります。 Apexコードは、カスタムコントローラーとして動作します。(または、コントローラーエクステンションは、メインページコントローラーとして) そして、Salesforceオブジェクトはモデルとして動作します。 同じパターンで、Sencha Touchアプリケーションを構築します。しかし、MVCコンポーネントは、クライアントのJavaScriptアプリケーションとしてのみ存在します。 サーバー側ではなく、クライアント側で動作します。

次のコードをPocketCRM_Appコンポーネントに追加してください。Modelより上にコントローラーのコードを起きたいが、特に重要なことではありません。

//===============================================================================
//CONTROLLERS
//Controllers manage the communication of your application and the coordination between the
//views and the model; they listen for the events emitted by the views and react accordingly.
//===============================================================================    
//The controller for the Leads list view
Ext.define("PocketCRM.controller.Leads", {
  extend: "Ext.app.Controller",
 
  config: {
  },
 
  // Base Class functions.
  launch: function () {
    console.log("launch");
    this.callParent(arguments);
 
  //Load up the Store associated with the controller and its views. 
    console.log("load Leads");
    var leadsStore = Ext.getStore("Leads");
    leadsStore.load();
 
  },
 
  init: function () {
    this.callParent(arguments);
    console.log("init");
  }
 
});

このコードは、ちょっと特別で、Leadストアについてのメモです。 この時点で、なんの機能も構築してません。 私たちは、console.log() を使ってデバッグメッセージを記述します、あなたもそうしてみてください。 これは、非常に有効なデバッグ方法の1つです。しかし、console.logを表示できるデバッグツールを利用していないといけません。

もう一度、Visualforceページを再読み込みしてください。 前回同様、正しく表示されている事を確認してください。


リスト用ビュー追加

さて、Lead を表示するビューを追加しましょう。本当の楽しみはこれからです。

最初に、コントローラーコンポーネントより上に、次のコードを追加してください。

//===============================================================================
//VIEWS
//Views display data to your users and gather input from them; 
//they also emit events about your user interaction.
//===============================================================================
//The Lead list view.
Ext.define("PocketCRM.view.LeadsList", {
  extend: "Ext.Container",
 
  //It uses the base list class.
  requires: "Ext.dataview.List", 
  alias: "widget.leadslistview",
 
  config: {
 
  //Take up the full space available in the parent container.
    layout: {
      type: 'fit'
    },
 
    //Add the components to include within the list view. 
    items: [
    {
      //A simple top title bar. 
      xtype: "titlebar",
      title: "PocketCRM: Leads",
      docked: "top",
    }, 
    {
      //The main list and its properties. 
      xtype: "list",
      store: "Leads",
      itemId:"leadsList",
      onItemDisclosure: false,
      grouped: true,
             disableSelection: false,
 
      //The template for display if the Store is empty of records.
      //Note the style to control visual presentation.
      loadingText: "Loading Leads...",
        emptyText: '<div class="leads-list-empty-text">No leads found.</div>',
 
      //The template for the display of each list item representing one record.
      //One row will display for each record in the data Store.
      //The fields referenced are from the entity's Model. 
      itemTpl:
'<div class="list-item-line-main">{LastName}, {FirstName}</div>' + 
'<div class="list-item-line-detail">{Company}</div>' + 
  '<div class="list-item-line-detail">{Title} - Phone: {Phone} </div>' +
  '<div class="list-item-line-detail">{Email}</div>',
    }],
  }
});

このビューは、ただアプリケーションに繰り返し表示します。 画面全体を覆って2つのコンポーネントに分けられます。 最初のコンポーネントはシンプルなタイトルバーです。タイトルを表示するだけです。 後で、このコンポーネントにいくつかボタンを加えます。 二つ目のコンポーネントは、ステータスによって分類されたLeadsを表示する一覧です。 どんな情報があるかではなく、プロパティにtrueが設定されたものだけが表示されます。 データ自体を確認したければ、ストアを確認してください。

Leadアイテムレコードを一覧表示するために2つのitemTplテンプレートが定義されています。 1つはレコードがない場合用、もう一つはデータを表示する用です。 CSSをカスタマイズしたい場合は、VisualforceカスタムコンポーネントのPocketCRM_CSSで行います。

もう一度、Visualforceページを表示してください。正しく表示されることを確認してください。レコードが一覧に表示されているはずです、大丈夫ですね?


アプリケーションの完成

ここまで、ModelとViewを作りましたが、コントローラーで結びつけないといけません。 アプリケーションコンポーネントに戻り、次のコードを入れ替えてください。

Ext.application({
name: "PocketCRM",
 
  //Load the various MVC components into memory.
  models: ["Lead"],
  stores: ["Leads"],
  controllers: ["Leads"],
  views: ["LeadsList"],
 
  //The application's startup routine once all components are loaded.
  launch: function () {
 
    //Instantiate your main list view for Leads.
    var leadsListView = {
      xtype: "leadslistview"
    };
 
    //Launch the primary fullscreen view and pass in the list view.
    Ext.Viewport.add([leadsListView]);
 
  }
 
});

アプリケーション開始時、MVCコンポーネントを読み込みます。 その上、leadsListViewのインスタンスを生成します。 メインUIのビューポートを追加してください。

ページを更新して次のように表示されることを確認してください。

良くできました!! ストアのLeadレコードを表示するだけですが、好きなように変更できます。 Force.com IDEまたはDeveloper Consoleにおいて、Execute Anonymous ウィンドウから、ただ2行のアックスコードで、JSONを生成できます。 以下のコードを実行して、デバッグログで、ストアに読み込まれレルJSONを確認してみてください。(カンマの終わり、ブレスの配置に注意して見てください)

List<Lead> leadList = [SELECT FirstName ,LastName ,Company ,Title ,Phone ,Email ,Status FROM Lead];
system.debug(JSON.serializePretty(leadList));

ノードの属性について何も心配しなくて良い。Sencha Touchのストアは、不要な属性は無視します。


ステップ 7: モックデータをリアルなデータに置き換える

ここまで、仮のJSONデータを使って、クライアント側だけ作ってきました。 Apex コントローラークラスの ‘getter’ を使ってSalesforce.comからデータを取得してくるように書き換えましょう。 Apex テストメソッドがコントローラークラスで正しく動作しているか試します。 次が、Force.com環境での開発のベストプラクティスセールスフォースの最高のカバレッジテストになります。

Apexクラスメソッドを作成します。PocketCRMLeadControllerと次のスタブコードを置き換えてください。

public class PocketCRMLeadController {
    private string leads;
 
    //Constructor.
    public PocketCRMLeadController(){
 
        //Fetch a limited set of Leads to return to the Sencha Data Store on load. 
        List<Lead> leadsList = [SELECT 
                                  FirstName
                                  ,LastName
                                  ,Company
                                  ,Title
                                  ,Phone
                                  ,Email
                                FROM Lead LIMIT 25]; 
 
        //Serialize the list as JSON and assign to the private string member.
        leads = JSON.serialize( leadsList );
        system.debug('Leads as JSON: ' + leads);
 
    }
 
    //Public getter method to return the Leads as JSON to the view.
    public String getLeads() { 
 
        return leads; 
 
    }
 
}

クラスコンストラクタで、行数を制限されたSOQLクエリーを実行した、listローカル変数に入れます。 そして、JSON.serialize()メソッドを実行して、クラスメンバをJSON文字列に変換し格納します。

公開メソッドの’getter’、getLeads()を使い、最初のページをストアに読み込みます。 上記のように、テストメソッドに注意してください。 ストアと連携する前に、クライアント側が正しく動作していることを確認してください。 テストは、administrationページの Setup -> Develop -> Classes から行えます。 このテストは、テストメソッドで作られたモックデータを表示し、見た目で確認することと、デバッグログで確認することができる用方法です。

ストアとコントローラーで取得したデータを結びつける修正を行いましょう。 PocketCRM_Appに戻って、次の2つの変更を行ってください。

最初に、PocketCRM_Appの一番上のタグに属性を追加してください。

<apex:component controller="PocketCRMLeadController" >

次に、仮のJSONデータを消して、PocketCRM.store.Leadsの部分のJavaScriptコードを書き換えてください。 忘れないでください、メソッド名が、getLeads()だとしても、{!Leads}としてバインドします。

//The Lead Store, this version will simply load with mock JSON data.
Ext.define("PocketCRM.store.Leads", {
    extend: "Ext.data.Store",
    requires: "Ext.data.proxy.LocalStorage",
 
    config: {
 
        model: "PocketCRM.model.Lead",
 
        //Fetch the data from the custom Apex controller method 
        //which will return a simple list of Leads as JSON on load.  
        data: {!Leads},
 
        //Create a grouping; be certain to use a field with content or you'll get errors!
        groupField: "Status",        groupDir: "ASC",
 
        //Create additional sorts for within the Group.
        sorters: [{ property: 'LastName', direction: 'ASC'}, { property: 'FirstName', direction: 'ASC'}]        
    }
 
});

ページを再読み込みして、リストを表示してください。 今度は、Salesforceのデータベースから値が表示されているはずです。 1つもデータが無い場合は、”No Status Assigned”と表示されはずです。


ステップ 8: PocketCRMデモ版

では、iPhoneでどのように起動するのでしょうか? モバイルブラウザを起動して、SalesforceのログインURLに移動してください。 いつもの開発環境へログインしてください。 もちろん、Salesforceには小さな表示だけでしょう。しかし、一度ログインすれば、Apexページの名前を変えることができます。(一度表示されれば、ホームスクリーンかブックマークに加えましょう)


https://c.{SERVER_NAME}.visual.force.com/apex/PocketCRM

VisualforceのページでSencha Touchアプリケーションが起動するはずです。 最初に大きめなライブラリファイルをダウンロードするので、2、3秒かかるかもしれません。 一般的にライブラリ全体を読み込んで開発を行います。 しかし、最終的にSDK ビルダーでソースコードを圧縮したり、必要なコードだけを抽出して最適化することができます。

Salesforce Profileでは、モバイルユーザーのために自動的にリダイレクトする機能があるので、自分のアプリケーションをそこに配置することもできます。 それから、アプリケーション利用のためのプロファイルを設定してください。 ユーザーは、Salesforceにログインしたときに自動的にモバイルページにリダイレクトされます。 もちろん、ブラウザで動作させると旨く動作しないかもしれない。 しかし、このサンプルは、モバイルアプリケーションをリダイレクトする1つの方法です。


サマリー

ここまで、やってきたことをまとめてみましょう。

  1. Force.comの開発環境を準備して、Sencha TouchライブラリがWebからアクセスできることを確認しました。
  2. JavaScriptアプリケーションとカスタムCSS、2つのVisualforceコンポーネントを作りました。
  3. ライブラリとアプリケーションを配置したVisualforce ページを作りました。
  4. Sencha Touchを利用して、アプリケーションのためにStore、Model、Controller、Viewを作りました。
  5. Salesforce.comデータベースからデータを取ってきて、コントローラーを追加し、Sencha Touchコンポーネントと結びつける前に、テストする方法を構築しました。それから、まず最初に作ったのは、ハードコーディングしたJSONデータをストアに読み込むものでした。
  6. 継続的に確認しながら、効果的なアジャイルスタイルで作ることができました。

モバイルアプリケーションにで何ができるか考えて見ましょう

いつ、どこでも動作する小さなモバイルアプリケーションは成功する(必ずしもそうではないが) Salesforce.comの事例は、完璧だ。 更新する度に複雑なアプリケーションを再構築することから解放されるが、これらでどんなことをさせるのが最善かを考える必要があります。 今後の展開のために、モバイルアプリケーションを研究するためにまずは、アップルのiOS ヒューマンインタフェースガイドラインを読み始めることをオススメします。


次回予告と宿題

次回は、LeadのCRUD操作を追加します。 @RemoteActionメソッドを利用して、プロキシ経由でデータをストアに読み込みます。

次回までに、ビデオなどをみてSencha Touchへの理解を深めておいたほうがよいでしょう。そして、サンプルとドキュメンテーションも見て、遊んでみてください。

関連情報:

  1. Sencha Touchのウェブサイト
  2. チュートリアル、ビデオ、APIドキュメンテーション(ガイダンスのSenchaカンファレンスのビデオを見てください)。それとは別に、オンラインのSencha Touchドキュメンテーションとガイダンスのページも見てください。
  3. MiamiCoder’s BLOG も見てください。いくつかSencha TouchとjQueryとか他のフレームワークの上級チュートリアルがあります。
  4. TwitterのPat Pattersonをフォローしてください。彼は、Force.comのすばらしいデベロッパーエバンジェリストの一人です。
  5. そして、もちろんdeveloper.force.comへ移動して、モバイル関連のコンテンツを入手してください。



執筆者 Don Robins のプロフィール

フレームワークベースのカスタムビジネスアプリケーション構築において 20 年以上にわたる経験を持つ。2009 年からは Force.com のコンサルタント兼アーキテクトとして多岐にわたるプロジェクトに関わり、最近では特にモバイルインテグレーションに専念している。Salesforce.com 認定上級デベロッパーの資格を有しコンサルティングやメンタリングを行うかたわら、Salesforce 認定インストラクターとして開発者の養成に従事。Salesforce の提供する全レベルの集合および一社研修をアメリカ内外で行っている。デベロッパー、アーキテクト、チームリード、テクニカルメンター、認定アジャイルスクラムマスターとしての長年の経験と実績、および開発者コミュニティーにおけるリーダーシップを背景に初心者から上級アーキテクトまで幅広い層の開発者の指導を担当。即戦力に繋がる演習とそのダイナミックなスタイルには特に定評が高く、これまで Salesforce より「四半期におけるベストインストラクター」の賞が贈られている。 サンフランシスコに拠点を置く Outformations, Inc.の代表者として、クラウドソリューションの支援サイトForceMentor.comを運営。

PAGE TOP

Copyright © 2006-2014 Xenophy.CO.,LTD All rights Reserved.