現在表示中:

単一ページアプリケーション(SPA)はクリティカルマスに達しており、Web テクノロジーでシームレスなエクスペリエンスを生成するための最も効果的なパターンであると広く考えられています。SPA パターンに従って作成できるアプリケーションは、デスクトップやモバイルのアプリケーションとまったく同じように機能しますが、オープン Web 標準を基盤としていることから多数のデバイスプラットフォームやフォームファクターで実行できます。

一般に、SPA は従来のページベースの Web サイトよりも高いパフォーマンスを発揮します。これは、SPA が通常、HTML ページ全体(CSS、JS、サポートするフォントコンテンツなど)を 1 回だけ読み込み、その後はアプリで状態の変更が発生するたびに必要なものだけを読み込むからです。状態の変更の発生に必要なものは、選択するテクノロジーのセットによって異なります。通常は、既存の「ビュー」を置き換える単一の HTML フラグメント、新規ビューを接続するための JS コードブロックの実行、必要に応じたクライアント側でのテンプレートのレンダリングが含まれます。状態の変更の速度は、テンプレートのキャッシュメカニズムをサポートすることで、または Adobe PhoneGap を使用する場合はテンプレートコンテンツへのオフラインアクセスによって、さらに改善することができます。

AEM 6.1 では、AEM アプリを利用して SPA をビルドおよび管理できます。この記事では、SPA の背後にある概念および AngularJS を活用して App Store および Google Play にブランドを公開する方法について説明します。

AEM アプリでの SPA

AEM アプリで単一ページアプリケーションフレームワークを使用すると、パフォーマンスの高い AngularJS アプリを実現できると同時に、作成者(または技術ユーザー以外のユーザー)は、タッチ操作用に最適化されたドラッグアンドドロップ編集環境でアプリのコンテンツを作成および管理できます(この環境は従来、Web サイト管理用でした)。AEM でビルドしたサイトが既に存在する場合があります。AEM アプリでは、コンテンツ、コンポーネント、ワークフロー、アセットおよび権限を簡単に再利用することができます。 

AngularJS アプリケーションモジュール

AEM アプリでは、アプリのトップレベルのモジュールを取りまとめるなど、AngularJS 設定の多くが自動で処理されます。デフォルトでは、このモジュールは「AEMAngularApp」という名前で、その生成を行うスクリプトは /libs/mobileapps/components/angular/ng-page/angular-app-module.js.jsp にあります(オーバーレイすることもできます)。 

アプリの初期化の一環として、アプリが依存する AngularJS モジュールを指定します。アプリで使用されるモジュールのリストは、/libs/mobileapps/components/angular/ng-page/angular-module-list.js.jsp にあるスクリプトで指定されていますが、独自のアプリのページコンポーネントでオーバーレイしてアプリで必要になる他の AngularJS モジュールを取り込むことができます。一例として、上記のスクリプトを Geometrixx 実装(/apps/geometrixx-outdoors-app/components/angular/ng-geometrixx-page/angular-module-list.js.jsp にあります)と比較してみてください。

アプリ内の異なる状態間の移動をサポートするために、angular-app-module スクリプトはトップレベルアプリページのすべての下位のページを繰り返し処理して、一連の「ルート」を生成し、Angular の $routeProvider サービスに各パスを設定します。これが実際にどのようになるかを示した例については、Geometrixx Outdoors サンプルアプリで生成された angular-app-module スクリプトを参照してください(リンクには、ローカルインスタンスが必要です)。http://localhost:4502/content/phonegap/conference-app/en/home.angular-app-module.js

生成された AEMAngularApp を詳細に見ると、一連のルートが次のように指定されています。

$routeProvider
.when('/content/phonegap/geometrixx-outdoors/en/home/products/:id', {
    templateUrl: 'home/products.template.html',
    controller: 'contentphonegapgeometrixxoutdoorsenhomeproducts'
})

特に上記のサンプルは、パスの一部としてパラメーターを渡す例を示しています。この例では、指定したパターンを満たすパス(/content/phonegap/geometrixx-outdoors/en/home/products/:id)が要求された場合、パスは home/products.template.html テンプレートで処理され、「contentphonegapgeometrixxoutdoorsenhomeproducts」コントローラーを使用する必要があることを示しています。 

このルートが要求されたときに読み込むテンプレートは、templateUrl プロパティで指定されています。このテンプレートは、ページにインクルードされた AEM コンポーネントの HTML と、アプリケーションのクライアント側を接続するために必要な AngularJS ディレクティブが含まれたものになります。Geometrixx コンポーネントでの AngularJS ディレクティブの例については、スワイプカルーセルの template.jsp(/apps/geometrixx-outdoors-app/components/swipe-carousel/template.jsp)の 45 行目を参照してください。

ページコントローラー

Angular におけるコントローラーの説明は、「Angular スコープを補強するために使用される JavaScript コンストラクター関数です」というものです(出典)。AEM アプリの各ページはコントローラーに自動的に接続されますが、このコントローラーは「angular」の「frameworkType」を指定する任意のコントローラーで補強される場合があります。一例として ng-text コンポーネント(/libs/mobileapps/components/angular/ng-text)および cq:template ノード(このコンポーネントがページに追加されるたびに、確実にこの重要な frameworkType プロパティを含めます)を参照してください。

さらに複雑なコントローラーの例については、ng-template-page controller.jsp スクリプトを開いてください(/apps/geometrixx-outdoors-app/components/angular/ng-template-page にあります)。特に興味深いのは実行時に生成される JavaScript コードで、次のようにレンダリングされます。

// Controller for page 'products'
.controller('contentphonegapgeometrixxoutdoorsenhomeproducts', ['$scope', '$http', '$routeParams',
    function($scope, $http, $routeParams) {
        var sku = $routeParams.id;
        var productPath = '/' + sku.substring(0, 2) + '/' + sku.substring(0, 4) + '/' + sku;
        var data = $http.get('home/products' + productPath + '.angular.json' + cacheKiller);
 
        /* ng-product component controller (path: content-par/ng-product) */
        data.then(function(response) {
            $scope.contentparngproduct = response.data["content-par/ng-product"].items;
        });
     
        /* ng-image component controller (path: content-par/ng-product/ng-image) */
        data.then(function(response) {
            $scope.contentparngproductngimage = response.data["content-par/ng-product/ng-image"].items;
        });
    }
])

上記の例では、「$routeParams」サービスからパラメーターを取得して、JSON データが格納されているディレクトリ構造にメッセージングしていることに注意してください。この方法で sku「id」を扱うことで、場合によっては数千もの個別の製品の製品データをレンダリングできる単一の製品テンプレートを提供できます。これは、(潜在的に)大規模な製品データベース内の項目ごとに個別のルートを必要とするよりも、拡大/縮小の可能性が非常に高いモデルです。

また、ここでは、2 つのコンポーネントが機能しています。ng-product は、上記の $http 呼び出しから抽出したデータでスコープを補強しています。このページにはこの他に ng-image もあり、これは、応答から取得した値でスコープを補強しています。Angular の「$http」サービスによって、各コンポーネントは、要求が終了し、この要求の内容が実現されるまで待機します。 

本作品は Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License によってライセンス許可を受けています。  Twitter™ および Facebook の投稿には、Creative Commons の規約内容は適用されません。

法律上の注意   |   プライバシーポリシー