Навигация в приложении NativeScript с Angular 2 Router

Навигация в приложении NativeScript с Angular 2 Router

Когда вы вдоволь наигрались с приложениями из одной страницы, вам придётся разобраться с навигацией между несколькими страницами. Сегодня мы как раз поговорим об этом.

Если вы следили за разработкой Angular 2, начиная с беты, то видели, что компоненты навигации кардинально менялись почти в каждом релизе. А те, кто наблюдал за NativeScript и Angular 2, также знают, что компания Telerik использовала все имеющиеся возможности Angular 2 в их текущем состоянии. Именно поэтому навигация в приложениях NativeScript Angular 2 менялась так часто за прошедший год. Однако, Angular 2 теперь официально вышел и Angular 2 Router не будет больше так сильно меняться.

Мы рассмотрим несложную навигацию между двумя компонентами Angular 2 в мобильном приложении на NativeScript под Android и iOS, используя стабильный Angular 2 Router.

Как всегда, мы начнём с чистого проекта NativeScript. Выполните в консоли следующие команды:

tns create MyProject --ng
cd MyProject
tns platform add ios
tns platform add android

В этом проекте мы используем два разных роутера, ни один из которых не включен в базовый шаблон NativeScript. Выполните следующие команды в папке app вашего проекта:

mkdir -p components/page1
mkdir -p components/page2
touch components/page1/page1.ts
touch components/page1/page1.html
touch components/page2/page2.ts
touch components/page2/page2.html

Если вам не удалось выполнить команды mkdir и touch или вам просто лень это делать, то просто создайте эти папки и файлы вручную.

Посмотрим сначала на вторую страницу нашего приложения, или, другими словами, страницу, на которую мы планируем перейти.

Откроем файл app/components/page2/page2.ts и вставим следующий код:

import {Component} from "@angular/core";

@Component({
selector: "page2",
templateUrl: "./components/page2/page2.html",
})
export class Page2Component {

public constructor() {}

}
В этом TypeScript коде нет ничего особенного, мы просто привязываем к нему соответствующий файл HTML. Не забудьте создать класс Page2Component.

После этого откроем файл app/components/page2/page2.html и добавим такую разметку:






Здесь мы создаём верхнюю панель с кнопкой «Назад» и пустой макет. Пока оставим название страницы в панели такой, этого более чем достаточно для понимания, на какой мы находимся странице.

Теперь перейдём к первой странице, она будет и основной при открытии приложения.

Откроем файл app/components/page1/page1.ts и добавим следующий TypeScript код:

import {Component} from "@angular/core";
import {Router} from "@angular/router";

@Component({
selector: "page1",
templateUrl: "./components/page1/page1.html",
})
export class Page1Component {

public constructor(private router: Router) {

}

public onTap() {
this.router.navigate(["page2"]);
}

}
Вообще этот код сильно похож на тот, что мы прописали во второй странице. Однако, здесь мы добавили метод onTap и импортировали компонент Angular 2 Router. После добавления роутера в конструктор, мы можем использовать его для навигации к любому доступному роуту.

У нас пока нет роутов, но мы вполне можем предположить, что page2 соответствует нашей второй странице. Через минуту мы это исправим.

Откроем файл app/components/page1/page1.html и добавим в него следующую разметку HTML:






Обратили внимание на навигационную кнопку, вызывающую метод onTap при нажатии? Так будет работать навигация.

Но мы ещё не закончили. Помните, я говорил, что у нас ещё нет роутов? Нам нужно их создать.

Создадим файл app/app.routing.ts в папке проекта. В этот файл добавим такой код:

import { Page1Component } from "./components/page1/page1";
import { Page2Component } from "./components/page2/page2";

export const appRoutes: any = [
{ path: "", component: Page1Component },
{ path: "page2", component: Page2Component }
];

export const appComponents: any = [
Page1Component,
Page2Component
];

Мы импортировали все имеющиеся страницы в первых строках файла. Зададим доступные роуты в массиве appRoutes, где path это значение, используемое в навигации TypeScript, а component это компонент, соответствующий заданному path.

Чтобы сэкономить немного времени в следующем шаге, мы создадим массив всех доступных компонентов.

На следующем шаге мы включим информацию о роутах во всемогущий блок @NgModule, находящийся в файле app/main.ts. Этот файл будет примерно такой:

// this import should be first in order to load some required settings (like globals and reflect-metadata)
import { platformNativeScriptDynamic, NativeScriptModule } from "nativescript-angular/platform";
import { NgModule } from "@angular/core";
import { AppComponent } from "./app.component";
import { NativeScriptRouterModule } from "nativescript-angular/router";
import { appComponents, appRoutes } from "./app.routing";

@NgModule({
declarations: [AppComponent, ...appComponents],
bootstrap: [AppComponent],
imports: [
NativeScriptModule,
NativeScriptRouterModule,
NativeScriptRouterModule.forRoot(appRoutes)
],
})
class AppComponentModule {}

platformNativeScriptDynamic().bootstrapModule(AppComponentModule);
Мы импортировали NativeScriptRouterModule и константы, заданные перед этим в файле app/app.routing.ts.

В блоке @NgModule мы определили все компоненты из массива appComponents в свойстве declarations. Импортировали NativeScriptRouterModule и доступные роуты в свойстве imports.

Всё почти готово!

Ещё хорошо бы сразу определить, откуда эти роуты будут видны. Отроем файл app/app.component.html и заменим всю HTML разметку следующей:


Теперь при запуске приложения навигация между страницами будет работать как надо.

Передача параметров между роутами

А что, если вам понадобится передать кое-какую информацию между роутами? Как вариант, можно передать идентификатор из списка, а затем запросить этот идентификатор из второй страницы.

Немного изменим наш код, чтобы можно было так и сделать.

Откроем файл app/app.routing.ts и изменим следующую строку:

{ path: "page2/:name", component: Page2Component }
Здесь мы добавили /:name в path. Теперь мы можем передать переменную, представляющую name.

Чтобы передать данные из первой страницы, откроем файл app/components/page1/page1.ts и изменим команду навигации вот так:

this.router.navigate(["page2", "Nic Raboy"]);
Здесь мы передаём строку с моим именем в навигационном запросе. На второй странице нам нужно ожидать эту переменную и получить её.

В файле app/components/page2/page2.ts заменим код на следующий:

import {Component} from "@angular/core";
import {ActivatedRoute} from "@angular/router";

@Component({
selector: "page2",
templateUrl: "./components/page2/page2.html",
})
export class Page2Component {

public fullName: string;

public constructor(private route: ActivatedRoute) {
this.route.params.subscribe((params) => {
this.fullName = params["name"];
});
}

}
Для получения данных с главной страницы, компонент ActivatedRoute должен быть импортирован. В методе constructor мы подписались на параметры навигации и присвоили их переменной fullName. После этого мы можем вывести значение этой переменной в UI.

В файле app/components/page2/page2.html изменим HTML разметку на такую:







На экран будет выведено “Hello Nic Raboy”, когда вы перейдёте на эту страницу.

Заключение

Вот так просто можно использовать стабильную версию Angular 2 Router для построения навигации между страницами в приложении NativeScript под Android и iOS. Мы построили не просто навигацию, но ещё и предусмотрели возможность передать параметр с данными между страницами.

Видеоверсия этой статью (на англ.):.

Nic Raboy Navigating A NativeScript App With The Angular 2 Router

Leave a Comment