Show Menu
トピック×

シングルページアプリケーション

単一ページアプリケーションフレームワークを基にしたクライアント側レンダリング(React など)が必要なプロジェクトでは、SPA エディターを使用することをお勧めします。 詳細情報 を参照してください。
シングルページアプリ (SPA)は、Webテクノロジーを使用したシームレスなエクスペリエンスを構築するための最も効果的なパターンとして広く見なされ、重要な一般大衆に達しています。 SPAパターンに従うと、デスクトップまたはモバイルアプリケーションと同じ動作を行うが、オープンWeb標準での基盤に起因する多数のデバイスプラットフォームとフォームファクタに到達するアプリケーションを作成できます。
Generally speaking, SPAs appear more performant than traditional page-based web sites because they typically load a complete HTML page only once (including CSS, JS, and supporting font content), and then load only exactly what is necessary each time a change of state occurs in the app. 状態の変更の発生に必要なものは、選択するテクノロジーのセットによって異なります。通常は、既存の「ビュー」を置き換える単一の HTML フラグメント、新規ビューを接続するための JS コードブロックの実行、必要に応じたクライアント側でのテンプレートのレンダリングが含まれます。状態の変更の速度は、テンプレートのキャッシュメカニズムをサポートすることで、または Adobe PhoneGap を使用する場合はテンプレートコンテンツへのオフラインアクセスによって、さらに改善することができます。
AEM 6.1 では、AEM アプリを利用して SPA をビルドおよび管理できます。This article will provide an introduction to the concepts behind the SPA and how they leverage AngularJS to bring your brand to the App Store and 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 サービスに各パスを設定します。For an example of how this looks in practice, take a look at the angular-app-module script generated by the Geometrixx Outdoors app sample: (link requires a local instance) 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ディレクティブの例を見るには、swipe-carouselのtemplate.jsp(/apps/geometrixx-outdoors-app/components/swipe-carousel/template.jsp)の45行目を見てみましょう。

ページコントローラー

Angular におけるコントローラーの説明は、「Angular スコープを補強するために使用される JavaScript コンストラクター関数です」というものです( source ) Each page in an AEM App is automatically wired up to a controller that can be augmented by any controller which specifies a frameworkType of angular . 一例として ng-text コンポーネント(/libs/mobileapps/components/angular/ng-text)および cq:template ノード(このコンポーネントがページに追加されるたびに、確実にこの重要な frameworkType プロパティを含めます)を参照してください。
より複雑なコントローラーの例を見るには、/apps/geometrixx-outdoors-app/components/angular/ng-template-pageにあるng-template-page controller.jspスクリプトを開きます。 特に興味深いのは実行時に生成される 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;
        });
    }
])

In the above example, you will note that we are taking a parameter from the $routeParams service and then massaging it into the directory structure that our JSON data is stored in. By dealing with the sku id in this manner, we are able to deliver a single Product template that can render the product data for potentially thousands of distinct products. これは、(潜在的に)大規模な製品データベース内の項目ごとに個別のルートを必要とするよりも、拡大/縮小の可能性が非常に高いモデルです。
There are also two components at work here: ng-product augments the scope with the data it extracts from the above $http call. このページにはng-imageもあり、応答から取得した値でスコープを増補します。 By virtue of Angular's $http service, each component will wait patiently until the request is finished and the promise it created is fulfilled.

次の手順

シングルページアプリケーションについて学習したら、 PhoneGap CLI によるアプリの開発 を参照してください。