コアコンセプト / アプリケーションアーキテクチャ

アプリケーションアーキテクチャ

この記事では、Core Frameworkを使って構築されたNativeScriptアプリケーションのアーキテクチャーについて解説します。アプリのエントリポイント、モジュールへの分解、アプリケーションのスタイル設定、データバインディングを含みます。

エントリーポイント

コアNativeScriptアプリケーションのエントリポイントはapp rootフォルダにあるpackage.jsonファイルのmainプロパティで宣言されます。 これは、TypeScriptプロジェクトを作成したときは、通常app.jsまたはapp.tsです。 このファイルを使用してアプリレベルの初期化を実行できますが、ファイルの主な目的はアプリのルートモジュールに制御を渡すことです。 これを行うには、application.run()メソッドを呼び出し、moduleNameで指定されるナビゲーションエントリーパスを、/appフォルダを基準にしたルートモジュールへのパスとして渡す必要があります。

// app.js
const application = require("tns-core-modules/application");
application.run({ moduleName: "app-root" });
// app.ts
import * as application from "tns-core-modules/application";
application.run({ moduleName: "app-root" });
重要:application.run()メソッド呼び出しの後にコードは配置しないでください。iOS上では実行されません。

重要:NativeScript 4.0.0より前のバージョンでは、start()メソッドはページをラップする基礎となるルートFrameインスタンスを自動的に作成しました。 新しいrun()メソッドは、提供されたモジュールのルート要素をアプリケーションのルート要素として設定します。 これは事実上Page以外にもTabViewSideDrawerなどを、あなたのアプリのルートに持つことができることを意味します。 start()メソッドは廃止予定です。

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

コアNativeScriptフレームワークはモジュールに分かれています。最低限、モジュールはUIマークアップを持つ1つの.xmlファイルで表されます。 そこから、ビジネスロジックを実行するためのバックエンドの.jsファイル、スタイルのための1つの.cssファイルを追加することもできます。 これらの追加ファイルにとって重要なことは、.xmlファイルと同じ名前を共有することです。 たとえば、次のファイルは1つのモジュールを構成します。

ビジネスロジックファイルによってエクスポートされるすべての機能は、テンプレートへのバインドに使用できます。 ビジネスロジックファイルは、イベントを処理したり、UIにコンテキストをバインドしたりするのに適した場所です。 次の例は、Pageコンポーネントのloadedイベントです。

<!-- home-page.xml -->
<Page class="page" loaded="onPageLoaded">
	<StackLayout>
		<Label text="Hooray! Home Page loaded!"/>
	</StackLayout>
</Page>
// home-page.js
function onPageLoaded(args) {
	console.log("Page Loaded");
}
exports.onPageLoaded = onPageLoaded;
// home-page.ts
import { EventData } from "tns-core-modules/data/observable";

export function onPageLoaded(args: EventData): void {
console.log("Page Loaded");
}
/* home-page.css */
.page {
	background-color: teal;
}
モジュールの命名規則が定められていることに注意してください。 それらのファイル名は、-rootまたは-pageのどちらかで終わり、モジュールのタイプを示します。命名規則は必須ではありません。 それは、より簡単で楽なwebpackのバンドルのために定められています。 (訳註:webpackを使用したビルドを行う場合、デフォルトではファイル名の末尾が-rootか-pageで終わるファイルのみをバンドルします。従って、ファイル名はこのルールに従って名付けることを強く推奨します。)

ルートモジュール

これらのモジュールはUIコンテナのルートとして使用されます。現在、NativeScriptアプリには2種類のUIコンテナしかありません。

ルートモジュールは、そのコンテンツのルートに1つのコンポーネントしか持てません。 あなたは事実上あらゆるUIコンポーネントをルートとして置くことができますが、最も一般的に使用されるコンポーネントは子を持つことができるレイアウト・・・TabViewSideDrawerFrameです。 Frameコンポーネントは子を持つことはできませんが、複数のページ・モジュール間を遷移し、表示することができます。

UIモジュールが消えるまで、ルートモジュールはナビゲーションに関係なくロードされています。 これは基本的に、アプリのルートモジュールは常にロードされることを意味します。 モーダルビュールートモジュールは、モーダルビューが閉じられるとアンロードされます。

アプリルートモジュールの例を次に示します。

<!-- app-root.xml -->
<Frame loaded="onFrameLoaded" defaultPage="home-page" />
// app-root.js
function onFrameLoaded(args) {
	console.log("Frame Loaded");
}
exports.onFrameLoaded = onFrameLoaded;
// app-root.ts
import { EventData } from "tns-core-modules/data/observable";

export function onFrameLoaded(args: EventData): void {
	console.log("Frame Loaded");
}

ページモジュール

これらのモジュールはページを表し、Frameコンポーネントによって前方および後方ナビゲーションを実装するために使用されます。 次の2つのうちのいずれかの方法でこれらのモジュールをFrameに渡すことができます。

ナビゲーションについてはナビゲーションの記事で詳しく説明されています。

ページモジュールは、常にそのコンテンツのルートにPageコンポーネントを持つ必要があります。以下はページモジュールのコードサンプルです。

<!-- home-page.xml-->
<Page class="page" loaded="onPageLoaded">
	<StackLayout>
		<Label text="Hooray! Home Page loaded!"/>
	</StackLayout>
</Page>
// home-page.js
function onPageLoaded(args) {
	console.log("Page Loaded");
}
exports.onPageLoaded = onPageLoaded;
// home-page.ts
import { EventData } from "tns-core-modules/data/observable";

export function onPageLoaded(args: EventData): void {
	console.log("Page Loaded");
}
/* home-page.css */
.page {
	background-color: teal;
}

グローバルアプリスタイリング

NativeScript Coreフレームワークは、アプリケーション全体のスタイルを設定する方法も提供します。 そのためのデフォルトの場所app.cssは、アプリのルートフォルダー内のファイルです。 このファイルで宣言されているすべてのCSSルールは、すべてのアプリケーションモジュールに適用されます。

アプリケーション全体のCSSがロードされるファイルの名前を変更できます。 次のようにapplication.run()メソッドが呼び出される前に変更を加える必要があります。

var application = require("tns-core-modules/application");
application.setCssFileName("style.css");

application.run({ moduleName: "main-page" });
import * as application from "tns-core-modules/application";
application.setCssFileName("style.css");

application.run({ moduleName: "main-page" });

スタイリングについてはスタイリングの記事で詳しく説明されています。

複数画面のサポート

モバイルアプリケーションは、画面サイズやフォームファクタの異なるさまざまなデバイス上で実行されています。 NativeScriptは、画面のサイズ、プラットフォーム、現在のデバイスの向きに基づいてロードされるさまざまなファイル(.js、.css、.xmlなど)を定義する方法を提供します。 このアプローチは、Androidのマルチスクリーンサポートと多少似ています。 ファイルのロード時に尊重される、ファイル内に追加できる一連の修飾子(qualifiers)があります。ファイル名は次の通りです。

<file-name>[.<qualifier>]*.<extension>

次のセクションでは、サポートされている修飾子のリストを見ていきます。

画面サイズ修飾子

画面サイズ修飾子のすべての値は、密度に依存しないピクセル(DP)です。つまり、画面の物理的な寸法に対応しています。前提は、1インチあたり約160DPです。 たとえば、Androidのガイドラインによると、デバイスの小さい方の寸法が600dp(約3.75インチ)を超える場合、それはおそらくタブレットです。

例(タブレットとスマートフォンでXMLファイルを分ける):

プラットフォーム修飾子

例(プラットフォーム固有のファイル):

プラットフォーム修飾子はビルド時に実行され、その他は実行時に実行されます。たとえば、app.ios.cssファイルは、Androidプラットフォーム用にビルドするときには考慮されません。 反対に、画面サイズ修飾子は、アプリケーションが特定の画面サイズのデバイス上で実行された直後に考慮されます。

オリエンテーション修飾子

注釈:ページのロード時には、すべての修飾子が考慮されます。ただし、デバイスの向きを変更してもページのリロードは発生せず、現在のページも変更されません。

データバインディング

データバインディングは、アプリケーションのユーザーインターフェイス(UI)をデータオブジェクト(コード)に接続するプロセスです。 NativeScriptでは、各UIコンポーネントをいわゆるバインディングソースにバインドできます。 bindingContextプロパティを通じて各UIコンポーネントにバインディングソースを設定できます。 ただし、これはバインディングを実装するための最良の方法ではありません。 bindingContextプロパティは、ビジュアルツリー全体で継承可能です。 つまり、bindingContextを自分のモジュールのルートコンポーネントに設定することができ、それはすべての子コンポーネントで利用可能になります。 その後、バインディングは、mustache記法(訳註:「{{~}}」を用いた値の埋め込み)を使用してXMLで記述されます。

次の例では、ロードされたイベントハンドラにPagebindingContextを設定してから、そのプロパティをLabelテキストにバインドします。

<!-- home-page.xml-->
<Page class="page" loaded="onPageLoaded">
	<StackLayout>
		<Label text=""/>		<!-- 訳註: text="{{text}}" では? -->
	</StackLayout>
</Page>
// home-page.js
const fromObject = require("tns-core-modules/data/observable").fromObject;

function onPageLoaded(args) {
	const page = args.object;
	const source = fromObject({ text: "Hooray! Home Page loaded!" });
	page.bindingContext = source;
}
exports.onPageLoaded = onPageLoaded;
// home-page.ts
import { EventData, fromObject } from "tns-core-modules/data/observable";
import { Page } from "tns-core-modules/ui/page";

export function onPageLoaded(args: EventData): void {
	const page: Page = args.object;
	const source = fromObject({ text: "Hooray! Home Page loaded!" });
	page.bindingContext = source;
}

バインディングについてはデータバインディングの記事で詳しく説明されています。

入門

コアコンセプト

ユーザーインターフェース

ツール

ハードウェアアクセス

プラグインの開発

リリース

アプリテンプレート

パフォーマンスの最適化

フレームワークモジュール

ガイド

サポートを受ける

トラブルシューティング

Siedkick