この記事では、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" });
コア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;
}
これらのモジュールは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で記述されます。
次の例では、ロードされたイベントハンドラにPageのbindingContextを設定してから、そのプロパティを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;
}
バインディングについてはデータバインディングの記事で詳しく説明されています。