ユーザーインターフェイス / 基本

ユーザーインターフェイスの基本

NativeScriptモバイルアプリのユーザーインターフェイスはページで構成されています。 一般的に、ユーザーインターフェースのデザインは、XMLファイルの中に開発され格納されます。 スタイリングはCSSを介して行われ、ビジネスロジックはJavaScriptTypeScriptファイルで記述されます。 アプリのユーザーインターフェイスを開発するときは、各アプリケーション画面を別々のページに実装するか、タブビューを使用して単一のページにアプリケーション画面を実装することができます。 ページごとに、ページのレイアウトを保持する個別のXMLファイルが必要です。 NativeScriptが解析するXMLファイルごとに、フレームワークは同じ名前のJavaScriptもしくはTypeScriptファイルを探し、その中でビジネスロジックを実行します。

ホームページの宣言

各NativeScriptアプリには、アプリを起動したときに読み込まれるホームページが必要です。 "Application"モジュールのrunメソッドを呼び出してアプリのホームページを明示的に設定し、 目的のmoduleNameを指定してNavigationEntryを渡す必要があります。

NativeScriptナビゲーションフレームワークは、指定された名前のXMLファイルを探し、それをロードしてそれぞれのページに移動します。 NativeScriptが同じ名前のJavaScriptまたはTypeScriptファイルを検出すると、その中のコードを実行します。

var application = require("tns-core-modules/application");
// Start the application. Don't place any code after this line as it will not be executed on iOS.
application.run({ moduleName: "my-page" });
import application = require("tns-core-modules/application");
// Start the application. Don't place any code after this line as it will not be executed on iOS.
application.run({ moduleName: "my-page" });
注釈: NativeScript 4.0.0より前では、startメソッドは自動的に基礎となるルートFrameインスタンスを作成し、ページをラップしていました。 新しいrunメソッドは、提供されたモジュールのルート要素をアプリケーションのルート要素として設定します。 これは事実上、Page以外にも、TabViewSideDrawerのような他のアプリケーションのルーツを持つことができるということを意味します。 なお、startは廃止予定です。

"Frame"クラスのnavigateメソッドを使ってページ間を移動できます。 "Frame"クラスは、異なるページ間のナビゲーションを担当する論理単位を表します。 NativeScript 4以降では、各アプリは1つ以上のフレームを持つことができます。 フレームへの参照を取得するには、getFrameByIdメソッドを使います。 ナビゲーションに関する詳細な情報については、専用の記事があります。

ナビゲーションをトリガすると、NativeScriptは指定された名前のXMLファイルを探し、それをロードしてそれぞれのページに移動します。 NativeScriptが同じ名前のJavaScriptもしくはTypeScriptファイルを検出すると、その内部のコードを実行します。

// To import the "tns-core-modules/ui/frame" module:
let getFrameById = require("tns-core-modules/ui/frame").getFrameById;
const frame = getFrameById("myFrame");
// Navigate to page called “my-page”
frame.navigate("my-page");
// To import the "tns-core-modules/ui/frame" module:
import { getFrameById } from "tns-core-modules/ui/frame";
const frame = getFrameById("myFrame");
// Navigate to page called “my-page”
frame.navigate("my-page");
<Frame id="myFrame"/>
パスはアプリケーションルートからの相対パスです。 上記の例では、NativeScriptはプロジェクトのappディレクトリでmy-page.xmlファイルを探します(例:app/my-page.xml)。

ナビゲーション時にバインディングコンテキストを渡す

ページ遷移時にbindingContextを自動的に受け渡しできます。 これはコンテキストをナビゲーションのページのbindingContextにするための簡単な方法を提供します。 これを行う方法は、カスタムメソッドを指すbindingContextプロパティをnavigateメソッドに設定することです。

// To import the "ui/frame" module and "main-view-model":
let getFrameById = require("tns-core-modules/ui/frame").getFrameById;
const frame = getFrameById("myFrame");

const HelloWorldModel = require("./main-view-model").HelloWorldModel;
// Navigate to page called “my-page” and provide "bindingContext"
frame.navigate({
	moduleName: "my-page",
	bindingContext: new HelloWorldModel()
});
// To import the "ui/frame" module and "main-view-model":
import { getFrameById } from "tns-core-modules/ui/frame";
const frame = getFrameById("myFrame");

import { HelloWorldModel } from "./main-view-model"
// Navigate to page called “my-page” and provide "bindingContext"
frame.navigate({
	moduleName: "my-page",
	bindingContext: new HelloWorldModel()
});

カスタムコンテキストの受け渡し

特定のコンテキストを渡して自動bindingContextよりも多くの制御が必要な場合は、navigatedEntryオブジェクトのcontextプロパティを使用できます。 遷移後のページでは、navigatedToイベントおよび"navigaitonContext"プロパティを介して渡されたコンテキストを取得できます。

メインページからバインディングコンテキストを送信します。

// e.g. main-page.js
let getFrameById = require("tns-core-modules/ui/frame").getFrameById;
const frame = getFrameById("myFrame");
// Navigate to page called “sub-page” and provide "bindingContext"
frame.navigate({
	moduleName: "sub-page",
	context: { title: "NativeScript is Awesome!"}
});
// e.g main-page.ts
import { getFrameById } from "tns-core-modules/ui/frame";
const frame = getFrameById("myFrame");
// Navigate to page called “sub-page” and provide "bindingContext"
frame.navigate({
	moduleName: "sub-page",
	context: { title: "NativeScript is Awesome!"}
});

サブページからコンテンツを受信する。

// sub-page.js
function onNavigatedTo(args) {
	const page = args.object;
	page.bindingContext = page.navigationContext;
}
exports.onNavigatedTo = onNavigatedTo;
// sub-page.ts
import { Page } from "tns-core-modules/ui/page";
export function onNavigatedTo(args) {
	const page = <Page>args.object;
	page.bindingContext = page.navigationContext;
}
<!-- sub-page.xml -->
<Page xmlns="http://www.nativescript.org/tns.xsd" navigatedTo="onNavigatedTo">
	<Label text="" textWrap="true" />
</Page>

ビジネスロジックを実行

XMLファイルと同じ名前のJavaScriptまたはTypeScriptファイルが同じ場所にある場合、NativeScriptはそれをXMLファイルと一緒に読み込みます。 このJavaScriptファイルまたはTypeScriptファイルでは、イベントハンドラの管理、コンテキストのバインド、または追加のビジネスロジックの実行を行うことができます。

このmain-page.xmlの例では、ページはボタンで構成されています。 ボタンをタップすると、buttonTap関数がトリガされます。

<Page>
	<StackLayout>
		<Label id="Label1" text="This is Label!" />
		<Button text="This is Button!" tap="buttonTap" />
	</StackLayout>
</Page>

この例では、簡単なカウンターアプリを紹介します。カウンタのロジックはmain-page.jsファイルまたはmain-page.tsファイルに実装されています。

const view = require("tns-core-modules/ui/core/view");
let count = 0;
function buttonTap(args) {
	count++;
	let button = args.object;
	let parent = button.parent;
	if (parent) {
		let lbl = view.getViewById(parent, "Label1");
		if (lbl) {
			lbl.text = "You tapped " + count + " times!";
		}
	}
}
exports.buttonTap = buttonTap;
import { EventData } from "tns-core-modules/data/observable";
import { getViewById } from "tns-core-modules/ui/core/view";
import { Label } from "tns-core-modules/ui/label";
import { View } from "tns-core-modules/ui/core/view";

let count = 0;
export function buttonTap(args: EventData) {
	count++;
	let button = <View>args.object;
	let parent = button.parent;
	if (parent) {
		let lbl = <Label>getViewById(parent, "Label1");
		if (lbl) {
			lbl.text = "You tapped " + count + " times!";
		}
	}
}

ユーザーインターフェースから変数や関数にアクセスするには、それらをモジュール内のexportsオブジェクトで宣言する必要があります。 NativeScriptはXML宣言内の各属性値を、それぞれのプロパティまたはコンポーネントのイベントに設定します。 それぞれのプロパティが存在しない場合、NativeScriptは属性値をExpandoオブジェクトとして設定します。

ユーザーインターフェースコンポーネント

NativeScriptは、レイアウトやウィジェットなど、幅広い組み込みのユーザーインターフェイスコンポーネントを提供します。 独自のカスタムユーザーインターフェイスコンポーネントを作成することもできます。 NativeScriptがXMLファイルを解析するとき、モジュールエクスポート内の名前と一致するコンポーネントを探します。 たとえば、XMLファイルにButton宣言がある場合、NativeScriptはモジュールのエクスポート内でButton名を探します。

var Button = ...
...
exports.Button = Button;
export let Button = ...

デフォルトのコンテンツコンポーネント

最上位のユーザーインターフェイスコンポーネントは、ページやレイアウトなどのコンテンツコンポーネントです。 これらのコンテンツコンポーネントを使用すると、インタラクティブなユーザーインターフェイスコンポーネントを特定の方法で配置できます。

Page

アプリケーションページ(または画面)は、Pageモジュールのpageクラスのインスタンスです。 通常、アプリは複数のアプリケーション画面で構成されます。

pageLoadedイベントを使用してページが読み込まれると、いくつかのビジネスロジックを実行できます。 main-page.xmlでページのロードされた属性を設定する必要があります。

<Page loaded="pageLoaded">
<!-- Page content follows here -->
</Page>

main-page.jsまたはmain-page.tsファイルでロードするビジネスロジックを処理する必要があります。

function pageLoaded(args) {
	var page = args.object;
}
exports.pageLoaded = pageLoaded;
import { EventData } from "tns-core-modules/data/observable";
import { Page } from "tns-core-modules/ui/page";

// Event handler for Page "loaded" event attached in main-page.xml
export function pageLoaded(args: EventData) {
	// Get the event sender
	const page = <Page>args.object;
}

TabView

タブビューを使用すると、ユーザーインターフェースが複数のページに広がることを回避できます。代わりに、複数のタブを持つ1つのページを作成できます。

次のサンプルmain-page.xmlには、ラベル付きの2つのタブが含まれています。

<Page loaded="pageLoaded">
<TabView id="tabView1">
	<TabView.items>
		<TabViewItem title="Tab 1">
			<TabViewItem.view>
				<Label text="This is Label in Tab 1" />
			</TabViewItem.view>
		</TabViewItem>
		<TabViewItem title="Tab 2">
			<TabViewItem.view>
				<Label text="This is Label in Tab 2" />
			</TabViewItem.view>
		</TabViewItem>
	</TabView.items>
</TabView>
</Page>

それぞれのmain-page.jsまたはmain-page.tsは、IDで最初のタブを読み込み、その内容を表示します。

var getViewById = require("tns-core-modules/ui/core/view").getViewById;
function pageLoaded(args) {
	var page = args.object;
	var tabView1 = getViewById(page, "tabView1");
	tabView1.selectedIndex = 1;
}
exports.pageLoaded = pageLoaded;
import { EventData } from "tns-core-modules/data/observable";
import { getViewById } from "tns-core-modules/ui/core/view";
import { Page } from "tns-core-modules/ui/page";
import { TabView } from "tns-core-modules/ui/tab-view";

// Event handler for Page "loaded" event attached in main-page.xml
export function pageLoaded(args: EventData) {
	// Get the event sender
	var page = <Page>args.object;
	var tabView1 = <TabView>getViewById(page, "tabView1");
	tabView1.selectedIndex = 1;
}

ScrollView

ページ内にScrollViewを挿入して、ページまたはscrollViewで囲まれたコンテンツをスクロール可能にします。

<Page>
	<ScrollView>
		<!-- Scrollable content goes here -->
	</ScrollView>
</Page>

StackLayout

StackLayoutorientationを使用して、ページ内のユーザーインターフェイスコンポーネントを水平または垂直に配置します。

<Page>
	<StackLayout orientation="horizontal">
		<Label text="This is Label 1" />
		<Label text="This is Label 2" />
	</StackLayout>
</Page>

GridLayout

GridLayoutを使用して、ページ内のユーザーインターフェイスコンポーネントを柔軟なグリッド領域に配置します。

<Page>
	<GridLayout rows="*, auto" columns="250, *">
		<Label text="This is Label in row 0, col 0" />
		<Label text="This is Label in row 0, col 1" col="1" />
		<Label text="This is Label in row 1, col 0" row="1" />
		<Label text="This is Label in row 1, col 1" row="1" col="1" />
		<Label text="This is Label in row 0, col 0" rowSpan="2" colSpan="2" />
	</GridLayout>
</Page>

WrapLayout

スペースがいっぱいになるまでユーザーインターフェイスコンポーネントを行または列に配置し、WrapLayoutを使用して新しい行または列にラップします。 デフォルトでは、方向が指定されていない場合、WrapLayoutはアイテムを水平に配置します。

<Page>
	<WrapLayout>
		<Label text="This is Label 1" />
		<Label text="This is Label 2" />
		<Label text="This is Label 3" />
		<Label text="This is Label 4" />
	</WrapLayout>
</Page>

AbsoluteLayout

AbsoluteLayoutを使用して、左/上の座標でユーザーインターフェイスコンポーネントを配置します。

<Page>
	<AbsoluteLayout>
		<Label text="This is Label 1" left="30" top="70" />
	</AbsoluteLayout>
</Page>

カスタムコンポーネント

独自のXMLネームスペースを定義して、カスタムユーザーインターフェイスコンポーネントを作成できます。 カスタムコンポーネントは、XMLファイルまたはコードビハインドのJS/TS実装を介して作成できます。

コードによるカスタムコンポーネント

カスタムコンポーネントを使用したページ

サンプルのmain-page.xmlは、app/components/my-control.tsファイル (またはプレーンJavaScriptを使用している場合は*.js)の個別の宣言で定義されたカスタムコンポーネントを使用しています。

<!-- app/main-page.xml -->
<Page xmlns:customControls="components/my-control" navigatingTo="navigatingTo" class="page">
	<customControls:MyControl />
</Page>
カスタムコンポーネントの実装

app/components/my-control.tsまたはapp/components/my-control.jsで宣言されているこのサンプルカスタムコンポーネントは、MyControl変数をエクスポートし、main-page.xmlページ内に単純なカウンターを作成します。

// app/components/my-control.ts
import { StackLayout } from "tns-core-modules/ui/layouts/stack-layout/stack-layout";
import { Label } from "tns-core-modules/ui/label/label";
import { Button } from "tns-core-modules/ui/button/button";

export class MyControl extends StackLayout {
	constructor() {
		super();

		let counter: number = 0;
		const lbl = new Label();
		const btn = new Button();
		btn.text = "Tap me!";
		btn.on("tap", (args) => {
			lbl.text = "Tap " + counter++;
		});

		this.addChild(lbl);
		this.addChild(btn);
	}
}
// app/components/my-control.js
var __extends = this.__extends || function (d, b) {
	for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
	function __() { this.constructor = d; }
	__.prototype = b.prototype;
	d.prototype = new __();
};
var stackLayout = require("tns-core-modules/ui/layouts/stack-layout");
var label = require("tns-core-modules/ui/label");
var button = require("tns-core-modules/ui/button");
var MyControl = (function (_super) {
	__extends(MyControl, _super);
	function MyControl() {
		_super.call(this);
		var counter = 0;
		var lbl = new label.Label();
		var btn = new button.Button();
		btn.text = "Tap me!";
		btn.on(button.Button.tapEvent, function (args) {
			lbl.text = "Tap " + counter++;
		});
		this.addChild(lbl);
		this.addChild(btn);
	}
	return MyControl;
})(stackLayout.StackLayout);
exports.MyControl = MyControl;

xmlns宣言を使用してページ内のコードのみのコンポーネントを参照する場合、 コンポーネント実装を含むコードファイルまたはファイルを含むフォルダーを指す必要があります。 後者の場合、パッケージにpackage.jsonファイルを追加して、ファイルが適切に読み込まれるようにする必要があります。

コードファイルを含むXMLベースのカスタムコンポーネント

カスタムコンポーネントを使用したページ

サンプルのmain-page.xmlは、カスタムコンポーネントmy-control.xmlと、app/componentsフォルダー内の個別のファイルとして定義されたmy-control.tsコードビハインドを使用しています。

<!-- app/main-page.xml -->
<Page xmlns:comps="components" navigatingTo="navigatingTo">
	<comps:my-control />
</Page>
// app/main-page.ts
import { EventData } from 'tns-core-modules/data/observable';
import { Page } from 'tns-core-modules/ui/page';
import { HelloWorldModel } from './main-view-model';

export function navigatingTo(args: EventData) {
	let page = <Page>args.object;

	// the page binding context will be accerss in components/my-toolbar
	page.bindingContext = new HelloWorldModel();
}
// app/main-page.js
var main_view_model_1 = require("./main-view-model");
function navigatingTo(args) {
	var page = args.object;
	// the page binding context will be accerss in components/my-toolbar
	page.bindingContext = new main_view_model_1.HelloWorldModel();
}
exports.navigatingTo = navigatingTo;
カスタムコンポーネントの実装

app/components/my-control.xml内のカスタムコンポーネントは、ボタン、関連するバインディングプロパティとタップ機能を持つラベルを定義します。

<!-- app/components/my-control.xml -->
<StackLayout class="p-20" loaded="onLoaded">
	<Label text="This custom component binding is coming from the parent page" textWrap="true" />
	<Label text="Tap the button (custom component)" class="h1 text-center"/>
	<Button text="TAP" tap="{{ onTap }}" class="btn btn-primary btn-active"/>
	<Label text="{{ message }}" class="h2 text-center" textWrap="true"/>
</StackLayout>
// app/components/my-control.ts
import { EventData } from "tns-core-modules/data/observable";

export function onLoaded(args: EventData) {
	console.log("Custom Component Loaded");

	// you could also extend the custom component logic here e.g.:
	// let stack = <StackLayout>args.view;
	// stack.bindingContext = myCustomComponentViewModel;
}
// app/components/my-control.js
function onLoaded(args) {
	console.log("Custom Component Loaded");

	// you could also extend the custom component logic here e.g.:
	// let stack = args.view;
	// stack.bindingContext = myCustomComponentViewModel;
}
exports.onLoaded = onLoaded;
バインディングに使用されるビューモデル

main-pageには、ビューモデルによるバインドコンテキスト設定(MVVMパターン)があります。 以下の例のように、カスタムコンポーネントを介してバインディングコンテキストにアクセスできます。

// app/main-view-model.ts
import { Observable } from "tns-core-modules/data/observable";

export class HelloWorldModel extends Observable {

	private _counter: number;
	private _message: string;

	constructor() {
		super();

		// Initialize default values.
		this._counter = 42;
		this.updateMessage();
	}

	get message(): string {
		return this._message;
	}

	set message(value: string) {
		if (this._message !== value) {
			this._message = value;
			this.notifyPropertyChange('message', value)
		}
	}

	public onTap() {
		this._counter--;
		this.updateMessage();
	}

	private updateMessage() {
		if (this._counter <= 0) {
			this.message = 'Hoorraaay! You unlocked the NativeScript clicker achievement!';
		} else {
			this.message = `${this._counter} taps left`;
		}
	}
}
// app/main-view-model.js
var Observable = require("tns-core-modules/data/observable").Observable;

function getMessage(counter) {
	if (counter <= 0) {
		return "Hoorraaay! You unlocked the NativeScript clicker achievement!";
	} else {
		return counter + " taps left";
	}
}

function createViewModel() {
	var viewModel = new Observable();
	viewModel.counter = 42;
	viewModel.message = getMessage(viewModel.counter);

	viewModel.onTap = function() {
		this.counter--;
		this.set("message", getMessage(this.counter));
	}

	return viewModel;
}

exports.createViewModel = createViewModel;

カスタムコンポーネントの動的ロード

JavaScript/TypeScriptコンポーネントの動的ロード

純粋なJavaScriptコンポーネントをモジュールのエクスポートで見つけてロードします。コンポーネントはパスとその名前で指定されます。その後、JavaScriptファイルからのコードが実行されます。

import * as builder from "tns-core-modules/ui/builder";
let myComponentInstance = builder.load({
	path: "~/components/my-control",
	name: "MyControl"
});
let builder = require("tns-core-modules/ui/builder");
let myComponentInstance = builder.load({
	path: "~/components/my-control",
	name: "MyControl"
});
JavaScript/TypeScriptコンポーネントを使用したXMLの動的ロード

モジュールのエクスポート内の指定されたパスを介して指定されたXMLファイル名を見つけることによって、JavaScript分離コードを使用してXMLファイルをロードします。同じ名前のJavaScriptファイルが必要になり、XMLの分離コードとして機能します。

import * as builder from "tns-core-modules/ui/builder";
let myComponentInstance = builder.load({
	path: "~/components/my-control",
	name: "MyControl"
});
let builder = require("tns-core-modules/ui/builder");
let myComponentInstance = builder.load({
	path: "~/components/my-control",
	name: "MyControl"
});
UIビルダーは、コンポーネント名と同じ名前のCSSファイルを自動的にロードし、それを指定されたページに適用します。
let myComponentInstance = builder.load({
	path: "~/components/my-control",
	name: "MyControl",
	page: yourPageInstancex
});
let myComponentInstance = builder.load({
	path: "~/components/my-control",
	name: "MyControl",
	page: yourPageInstance
});

動的ロードと追加属性の受け渡し

このattributesオプションを使用して追加の引数を渡すことができます。

import * as builder from "tns-core-modules/ui/builder";
let myComponentInstance = builder.load({
	path: "~/components/my-control",
	name: "MyControl",
	attributes: {
		bindingContext: myBindingModel
	}
});
let builder = require("tns-core-modules/ui/builder");
let myComponentInstance = builder.load({
	path: "~/components/my-control",
	name: "MyControl",
	attributes: {
		bindingContext: myBindingModel
	}
});

## Gestures
All [UI Gestures](/ui/ns-ui-widgets/gestures)
(gestures.md) can be defined in XML. For example:
```XML
<Page>
	<Label text="Some text" tap="myTapHandler" />
</Page>
import { GestureEventData } from "tns-core-modules/ui/gestures";

export function myTapHandler(args: GestureEventData) {
	const context = args.view.bindingContext;
}
function myTapHandler(args) {
	const context = args.view.bindingContext;
}
exports.myTapHandler = myTapHandler;

バインディング

XMLでプロパティのバインディングを設定するには、二重中括弧構文を使用できます。バインディングに関しては、データバインディングの記事を参照してください。

プロパティバインディング

このサンプルmain-page.xmlには、ページのロード時にテキストが入力される単純なラベルが含まれています。

<Page>

	<Label text="{{ myTitle }}" />

</Page>

main-page.jsまたはmain-page.tsコードファイルは、ページのbindingContextを設定します。 bindingContextには、カスタムプロパティとその値が含まれます。 NativeScriptがmain-page.xmlを解析するとき、bindingContextの値がカスタム名プロパティに入力されます。

function navigatingTo(args) {
	const page = args.object;
	page.bindingContext = { myTitle: "NativeScript is Awesome!"};
}
exports.navigatingTo = navigatingTo;
import { EventData } from "tns-core-modules/data/observable";
import { Page } from "tns-core-modules/ui/page";

export function navigatingTo(args: EventData) {
	const page = <Page>args.object;
	page.bindingContext = { myTitle: "NativeScript is Awesome!"};
}
NativeScriptは、現在のコンポーネントのbindingContextまたはその親のbindingContextでカスタムプロパティを探します。 デフォルトでは、XMLで定義されているすべてのバインディングは双方向バインディングです。

イベントバインディング

このサンプルmain-page.xmlにはボタンが含まれています。 ボタンのテキストとボタンがトリガーするイベントは、対応するmain-page.jsまたはmain-page.tsファイルからページが読み込まれるときに決定されます。

<Page navigatingTo="navigatingTo">

	<Button text="{{ myProperty }}" tap="{{ myFunction }}" />

</Page>

このサンプルのmain-page.jsまたはmain-page.tsは、ページのbindingContextを設定します。 bindingContextには、ボタンテキストとその値のカスタムプロパティ、およびボタンがタップされたときにトリガーされるカスタム関数が含まれます。 NativeScriptがmain-page.xmlを解析すると、ボタンテキストにbindingContextの値が入力され、カスタム関数がタップイベントにバインドされます。

function navigatingTo(args) {
	const page = args.object;
	page.bindingContext = {
		myProperty: "Some text",
		myFunction: () => {
			// Your code
		}
	};
}
exports.navigatingTo = navigatingTo;
import { EventData } from "tns-core-modules/data/observable";
import { Page } from "tns-core-modules/ui/page";

export function navigatingTo(args: EventData) {
const page = <Page>args.object;
	page.bindingContext = {
		myProperty: "Some text",
		myFunction: () => {
			// Your code
		}
	};
}

リストビューバインディング

二重中括弧構文を使用して、アイテムを"listView"にバインドできます。 また、NativeScriptがlistViewのアイテムを作成するitemTemplateプロパティを使用してテンプレートを定義することもできます。

特にコンポーネントがテンプレートの一部である場合は、IDでコンポーネントにアクセスしないでください。コンポーネントプロパティを指定するにはバインディングを使用することをお勧めします。

NativeScriptは、listViewがページ内に読み込まれると、テンプレートからアイテムを作成できます。テンプレートとlistViewを使用するときは、listViewとそのアイテムのスコープに注意してください。

このサンプルmain-page.xmlでは、ListViewはラベルで構成され、各アイテムはテンプレートから作成されます。 各ラベルのテキストは、対応するアイテムのnameプロパティの値です

<Page navigatingTo="navigatingTo">

	<ListView id="listView1" items="{{ myItems }}">
		<ListView.itemTemplate>
			<Label id="label1" text="{{ name }}"  />
		</ListView.itemTemplate>
	</ListView>

</Page>

このサンプルmain-page.jsまたはmain-page.tsは、ページのbindingContextを設定します。 bindingContextには、ボタンテキストとその値のカスタムプロパティ、およびボタンがタップされたときにトリガーされるカスタム関数が含まれます。 NativeScriptがmain-page.xmlを解析すると、ボタンテキストにbindingContextの値が入力され、カスタム関数がタップイベントにバインドされます。

const view = require("tns-core-modules/ui/core/view");
function navigatingTo(args) {
	const page = args.object;
	page.bindingContext = { myItems: [{ name: "Name1" }, { name: "Name2" }, { name: "Name3" }] };

	// Will work!
	let listView1 = view.getViewById(page, "listView1");

	// Will not work!
	let label1 = view.getViewById(page, "label1");
}
exports.navigatingTo = navigatingTo;
import { EventData } from "tns-core-modules/data/observable";
import { Page } from "tns-core-modules/ui/page";
import { getViewById } from "tns-core-modules/ui/core/view";
import { ListView } from "tns-core-modules/ui/list-view";
import { Label } from "tns-core-modules/ui/label";

export function navigatingTo(args: EventData) {
const page = <Page>args.object;
	page.bindingContext = { myItems: [{ name: "Name1" }, { name: "Name2" }, { name: "Name3" }] };

	// Will work!
	const listView1 = <ListView>getViewById(page, "listView1");

	// Will not work!
	const label1 = 

ListView.itemTemplate内にいくつかの内部コレクションアイテムを表示するには、Repeaterを使用できます。

<Page>

	<ListView items="{{ myItems }}">
		<ListView.itemTemplate>
			<Repeater items="{{ mySubItems }}"  />
		</ListView.itemTemplate>
	</ListView>

</Page>

バインディング式

式をXMLのプロパティの値として設定するには、ここでmustache記法を使用することもできます。

NativeScriptは、bindingContextに設定されたObservableオブジェクトのプロパティが変更されるたびに、式を再評価します。 このバインディングは、ビューモデルからユーザーインターフェイスまでの一方向のバインディングです。

次のサンプルmain-page.xmlは、ラベルの値として式を設定する方法を示しています。

<Label text="{{ author ? 'by ' + author : '[no author]' }}" />
<Label text="{{ author || '[no author]' }}" />

複雑なプロパティパス

your.sub.property[name]

論理否定演算子と比較演算子

!,<, >, <=, >=, ==, !=, ===, !==,||, &&

単項演算子と二項演算子

+, -, *, /, %

三項演算子

a ? b : c

グルーピング

(a + b) * (c + d)

定数

numbers, strings, null, undefined

プラットフォーム固有の宣言

XMLでプラットフォーム固有のプロパティ値またはプラットフォーム固有のコンポーネントを宣言するには、次の構文を使用できます。

プラットフォーム固有のプロパティ値

<Page>
	<TextField ios:editable='False' android:editable='True' />
</Page>

プラットフォーム固有のコンポーネント宣言

<Page>
	<ios>
		<TextField />
	</ios>
	<android>
		<Label />
	</android>
</Page>
プラットフォームタグを入れ子にすることはできません。

小文字のコンポーネント宣言

NativeScript 1.3のリリース以降、小文字のダッシュを使用してUIを宣言できます。

<page>
<scroll-view>
	<stack-layout>
		<label ctext="Label" />
		<button text="Button" tap="tap" />
		...
入門

コアコンセプト

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

ツール

ハードウェアアクセス

プラグインの開発

リリース

アプリテンプレート

パフォーマンスの最適化

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

ガイド

サポートを受ける

トラブルシューティング

Siedkick