移动系统编程-Ionic 页面(Ionic Pages)

Ionic 页面

        Ionic 应用程序和大多数移动应用程序使用页面来利用小显示区域。Ionic 源代码结构中,每个页面都在一个单独的目录中,以便将页面的所有信息集中在一起。例如,tabs 启动应用程序在 app 目录中的目录结构如下。请看是否能看到与 Angular 应用程序的相似性。当克隆 tabs 启动应用程序时,它最初有以下文件夹和文件:

        前三个文件夹是页面,最后一个名为 tabs 的文件夹是应用程序底部的标签栏。应用程序本身在 Chrome 浏览器中测试时如下所示(在你修改它以适应自己的目的之前)。

        这是我们将在下面的组件部分中描述的标签栏组件。前三个页面由定义在 tabs 目录中的 tabs 组件启动。这三个页面对应于应用程序底部标签栏中的按钮文本。页面对应于应用程序底部的每个按钮。

        现在每个页面都用五个文件编码:三个 Typescript 文件、一个 SCSS 文件和一个 HTML 文件。例如,图示的 tab1 页面在 home 文件夹中编码为五个文件:

  • tab1.module.ts
  • tab1.page.html
  • tab1.page.scss
  • tab1.page.spec.ts
  • tab1.page.ts

        我们现在将查看 tab1.page.html 和 tab1.page.ts 文件的内容作为示例。tab1.page.ts 文件包含以下代码:

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

@Component({
  selector: 'app-tab1',
  templateUrl: 'tab1.page.html',
  styleUrls: ['tab1.page.scss']
})
export class Tab1Page {}

        请注意,Angular 模板位于 templateUrl 属性指示的 tab1.page.html 文件中。此组件的选择器标签是 <app-tab1>,将由 ionic 生成。tab1.page.html 文件作为此组件的模板,编码如下:

<ion-header>
  <ion-navbar>
    <ion-title>Tab 1</ion-title>
  </ion-navbar>
</ion-header>
<ion-content>
  <ion-card class="welcome-card">
    <ion-img src="/assets/shapes.svg"></ion-img>
    <ion-card-header>
      <ion-card-subtitle>Get Started</ion-card-subtitle>
      <ion-card-title>Welcome to Ionic</ion-card-title>
    </ion-card-header>
    <ion-card-content>
      <p>Now that your app has been created, you'll want to start building out features and components. Check out some of the resources below for next steps.</p>
    </ion-card-content>
  </ion-card>
  <ion-list lines="none">
    <ion-list-header>
      <ion-label>Resources</ion-label>
    </ion-list-header>
    <ion-item href="https://ionicframework.com/docs/">
      <ion-icon slot="start" color="medium" name="book"></ion-icon>
      <ion-label>Ionic Documentation</ion-label>
    </ion-item>
    <ion-item href="https://ionicframework.com/docs/building/scaffolding">
      <ion-icon slot="start" color="medium" name="build"></ion-icon>
      <ion-label>Scaffold Out Your App</ion-label>
    </ion-item>
    <ion-item href="https://ionicframework.com/docs/layout/structure">
      <ion-icon slot="start" color="medium" name="grid"></ion-icon>
      <ion-label>Change Your App Layout</ion-item>
    <ion-item href="https://ionicframework.com/docs/theming/basics">
      <ion-icon slot="start" color="medium" name="color-fill"></ion-icon>
      <ion-label>Theme Your App</ion-label>
    </ion-item>
  </ion-list>
</ion-content>

        注意模板中的 ionic 标签将被 ionic 组件解释。此代码定义了页面标题和内容部分,对应于上图中的页面。应用程序底部的菜单栏并未在此页面编码(在 tabs/ 目录中)。此外,显示为图形的 ionic 卡片在页面顶部定义。它引用了 src/assets/ 文件夹中的图形图像。

        这段代码定义了页面标题和内容部分,如页面图片所示。不过这里有一些缺失的内容。底部的菜单栏呢?这是由 ionic 页面控制器控制的,你将在下面的阅读中看到,这实际上是应用程序的根页面。

        为了解释菜单栏的来源,我们将从位于 src/app 目录中的 app.component.ts 文件开始,这正如你所知,是 Angular 应用程序的根。它包含以下代码:

import { Component } from '@angular/core';
import { Platform } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html'
})
export class AppComponent {
  constructor(
    private platform: Platform,
    private splashScreen: SplashScreen,
    private statusBar: StatusBar
  ) {
    this.initializeApp();
  }

  initializeApp() {
    this.platform.ready().then(() => {
      this.statusBar.styleDefault();
      this.splashScreen.hide();
    });
  }
}

        注意此代码的以下方面:

  1. 模板位于同一目录中的 app.html 页面中。它通过 @component 装饰器中的 templateUrl 属性包含在组件中。
  2. 尽管我们没有指定启动屏幕,但代码仍处理启动屏幕。原因是启动屏幕在存在时需要在 Ionic 和 Cordova 准备好之前显示。
  3. 在构造函数中定义了三个可注入服务。我们用于屏幕底部标签栏的可注入服务是 statusBar。
  4. 代码与应用程序的其他部分有多个链接。例如,构造函数的参数有一个 Platform 可注入服务作为第一个参数,用于初始化适当的平台信息(如 iOS 或 Android)。

        src/app/tabs 目录中的 tabs.page.ts 页面定义如下:

import { Component } from '@angular/core';
@Component({
  selector: 'app-tabs',
  templateUrl: 'tabs.page.html',
  styleUrls: ['tabs.page.scss']
})
export class TabsPage {}

        注意此组件仅依赖于模板来显示标签按钮。在 tabs.page.html 文件模板中声明了三个页面,如下所示:

<ion-tabs>
  <ion-tab-bar slot="bottom">
    <ion-tab-button tab="tab1">
      <ion-icon name="flash"></ion-icon>
      <ion-label>Tab One</ion-label>
    </ion-tab-button>
    <ion-tab-button tab="tab2">
      <ion-icon name="apps"></ion-icon>
      <ion-label>Tab Two</ion-label>
    </ion-tab-button>
    <ion-tab-button tab="tab3">
      <ion-icon name="send"></ion-icon>
      <ion-label>Tab Three</ion-icon>
    </ion-tab-button>
  </ion-tab-bar>
</ion-tabs>

        如你所见,<ion-tabs> 元素定义了导航栏中的所有三个选项,包括页面名称、页面标题和每个选项的显示图标。

        在我们看导航的细节之前,以下活动将修改一些文件,以便你可以看到它们如何影响应用程序。

基本页面

        自从 ionic 版本 4 以来,上一节中显示的 tabs 系统是建立在由 Angular 路由器提供的更基本的页面导航系统之上的。我们也可以直接使用它来处理自己的页面导航,因此我们不受 tabs 或其他导航(如稍后将看到的侧菜单模板)的限制。在本节中,我们将创建一个名为“name”的新页面,并导航到该页面。我们还将演示用于在页面之间传递信息的参数传递机制。

        首先,我们将使用 ionic 命令生成一个名为“name”的新页面。从应用程序的根目录输入命令:

ionic generate page name

        我们本可以在上一节中使用此命令生成新页面文件,但现在你已经了解了结构,编辑这些文件会更容易。

        我们将从上一节的 tab4 页面导航到此新页面。如果你没有让它工作,可以始终使用 tab3 页面。首先在 tab4.page.html 文件中添加一个按钮以转到我们的新页面。注意,我们将在稍后的研讨会上讨论 ionic 按钮。tab4.page.html 文件更新如下:

<ion-content>
  <h1>A new tab!</h1>
  <ion-button [routerLink]="['/name',params]">Go Name Page</ion-button>
</ion-content>

        这使用 <ion-button> 标签创建一个新的 ionic 按钮。[routerLink] 属性赋值可能对你来说很熟悉,因为它是 Angular 的路由链接系统,这是首选的页面导航系统。/name 参数是 name 页面的网址,这是用页面生成命令设置的。

        我们还必须在 tab4.page.ts 文件中将页面链接到路由器。它修改如下:

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

@Component({
  selector: 'app-tab4',
  templateUrl: 'tab4.page.html',
  styleUrls: ['tab4.page.scss']
})
export class Tab4Page {
  params: Object;
  constructor(private router:Router) {
    this.params = {name:"barry"};
  }
}

        这里导入了 Router 可注入服务并在构造函数中声明。我们还定义了一个参数对象,以便将一些数据传递到 name 页面。它在构造函数中初始化。如果你回到模板,你会看到 params 是传递给 routerLink 属性的数组的第二个元素。

        然后我们需要更新 name 页面以执行两个功能。首先,我们需要显示参数以演示其工作。我们还实现了一个“返回”按钮,以允许用户返回到 tab4 页面。

        我们更新模板 name.page.html,如下所示:

<ion-header>
  <ion-toolbar>
    <ion-title>Names</ion-title>
  </ion-toolbar>
</ion-header>
<ion-content>
  <p>Name is: {{nameData}}</p>
  <ion-button routerLink="/tabs/tab4" routerDirection="backward">Back</ion-button>
</ion-content>

        这显示了一个称为 nameData 的组件属性,该属性将包含传递给页面的参数。它还定义了一个按钮,允许用户返回到 tab4 页面。请注意,我们指定这是一个“后退”过渡。这是为了同步返回按钮,如果用户直接通过页面的 URL 访问页面。

        以上要求组件文件 name.page.ts 更新如下:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute} from '@angular/router';

@Component({
  selector: 'app-name',
  templateUrl: './name.page.html',
  styleUrls: ['./name.page.scss'],
})
export class NamePage implements OnInit {
  nameData: string;
  constructor(private route: ActivatedRoute) { }
  ngOnInit() {
    this.route.params.subscribe(
      (data) => { this.nameData = data.name;}
    );
  }
}

        此代码导入并声明了 ActiveRoute 可注入服务。此可注入服务提供一个 Observable 对象,该对象将参数传递到页面。我们需要一个 Observable 的原因是,页面可以在我们处理参数时显示(称为懒加载)。我们在 ngOnInit() 方法中订阅了 Observable,该方法是在 OnInit 接口中定义的。以下部分中我们将提到其他钩子。不要忘记导入接口!

        这就是所需的全部内容。页面生成将链接所有必要的组件并定义 URL。name 页面将如下所示。

        请注意,当我们显示新页面时,导航栏不可见。这是因为新页面不是标签页,而是独立页面。你应该通过以下活动测试这些导航组件。

页面生命周期事件

        由于 ionic 现在依赖于 Angular 页面路由,它也使用一些来自 Angular 的页面生命周期事件。我们在上面看到如何使用 OnInit 接口在页面初始化时调用 ngOnInit() 函数。ionic 还添加了一些不直接由于 Angular 路由器的事件。这些事件很重要,因为它们为我们提供了一种在用户在页面之间切换时初始化或清理数据的方法。

        一些有用的页面组件生命周期事件是:

  • ngOnInit() – 页面加载时执行。只执行一次,而不是每次页面显示时都执行。页面对象通常只创建一次,多次显示。
  • ngOnDestroy() – 页面组件销毁时执行。不过需要小心,ionic 缓存页面以供将来使用,因此只有当页面不再可访问时才会执行。
  • ionViewWillEnter() – 页面显示前执行
  • ionViewDidEnter() – 页面成为活动页面时执行
  • ionViewWillLeave() – 页面即将离开时执行
  • ionViewDidLeave() – 页面不再是活动页面时执行

        为了演示生命周期事件的使用,我们将在上一节的页面中添加两个生命周期事件。我们将插入一个事件函数,当组件对象加载时执行一次,并且在每次页面显示前执行。

@Component({
  selector: 'app-name',
  templateUrl: './name.page.html',
  styleUrls: ['./name.page.scss'],
})
export class NamePage implements OnInit {
  nameData: string;
  constructor(private route: ActivatedRoute) { }
  ngOnInit() {
    this.route.params.subscribe(
      (data) => { this.nameData = data.name;}
    );
    console.log("OnInit");
  }

  ngOnDestroy() {
    console.log("On Destroy");
  }

  ionViewDidLoad() {
    console.log("View did load");
  }

  ionViewWillEnter() {
    console.log("View will enter");
  }
}

        此示例没有任何实际原因来执行这些事件。然而,在有存储或网络需求的应用程序中,你会看到这些事件函数在初始化或清理存储在应用程序之外的数据时非常有用。

        更新上一节的页面之一以插入上述所有事件函数的控制台日志,例如,对于 ionViewDidLoad() 事件代码,插入:

console.log("ionViewDidLoad executed");

        在浏览器中执行应用程序并查看日志,查看事件何时触发。你应该在页面之间切换几次。

观看 - 向 Ionic 应用程序添加页面

        观看以下录音,了解如何向 Ionic 应用程序添加新页面,以创建多页面应用程序。

        请从这里访问录音中创建的代码:Week9.zip

        附加的 ZIP 文件是项目的源文件。我们没有包含完整的 Ionic 开发环境,因为它非常大。创建一个新的 Ionic 项目。删除新项目的 src 文件夹,解压缩附加的 ZIP 文件,并将 src 文件夹复制到新应用程序项目目录中。或者,你可以将这些文件中的代码复制并粘贴到你自己的项目文件中。按照在线课程说明在浏览器或 Android 模拟器/设备中编译、构建和运行应用程序。

        在以后的活动中,你将看到更多生命周期事件的使用。

其他 Ionic 功能

        我们将在以下模块中检查 Ionic 的本地接口。这是访问移动设备特殊硬件和软件功能的接口,是为 Cordova 插件设计的包装器。在本节中,我们将介绍两个其他的 Ionic 功能:ionicons 和主题。

图标

        你可能已经注意到前几节中对图标的引用。这些图标通过字符串名称选择,例如:

<ion-icon name="options"></ion-icon>

        此声明指定应插入名为“options”的图标。

        默认情况下,Ionic 提供大量图标供你使用。你可以在 Ionic 网站上查看图标列表及其外观:Ionic 图标

        注意名称 ionicon 有时用于 Ionic 图标,这几乎与标签名称匹配。

        Ionic 还维护了两套图标,一套是 iOS 版本,另一套是 Material Design (md) 版本,用于 Android 和其他系统。此外,iOS 图标有两个版本,active 和 inactive,其中 active 是默认状态。这些图标的外观取决于 isActive 属性值。例如,我们可以显示 iOS 应用程序的“bonfire”图标的非活动版本:

<ion-icon name="bonfire" isActive="false"></ion-icon>

        Ionic 会自动选择正确的图标版本(ios 或 md)进行显示。不过,你可以使用 ios 和 md 属性为每个平台指定不同的图标。此外,通过使用扩展的图标名称可以覆盖 ionic 的自动选择,例如“md-bonfire”是 android 版本,无论是否部署到 iOS 系统,都会显示为 android 版本。

        例如,在 Android 设备上显示 iOS 图标的活动和非活动版本,以下两个图标声明将显示“brush”图标的 iOS 活动和非活动版本。

<ion-icon name="ios-brush"></ion-icon>
<ion-icon name="ios-brush" isActive="false"></ion-icon>

主题

        Ionic 还支持主题,这与我们之前提到的 Sass 样式格式有关。主题允许你更改 ionic 应用程序的外观,赋予其独特甚至独一无二的风格。在本单元中我们没有时间讨论主题,但你可以自行尝试。Ionic 主题描述在:Ionic 主题

        Ionic 主题是通过 Sass(Syntactically Awesome Style Sheets)脚本/样式语言实现的。Sass 在语法上是对熟悉的 CSS 语言的扩展,就像 Typescript 在语法上是 JavaScript 的扩展一样。这意味着 CSS 代码在 Sass 样式表中将正常工作。它也作为预处理器实现,输出 CSS 样式表。这也类似于 Typescript 编译器生成 JavaScript 代码的方式。

        Sass 的开发者声称以下是对 CSS 的主要添加(参见:Sass 指南):

  1. 变量。Sass 允许你定义变量,可以在整个 Sass 定义中重复使用。这很有用,因为我们可以定义包含许多变量插入的 Sass 代码,只需更改变量值即可在整个代码中传播更改。
  2. 嵌套。在 CSS 中,每个样式类必须按顺序定义。Sass 允许嵌套定义,以便可以在一个聚合名称下定义一组定义。嵌套允许像 HTML 标签的自然嵌套一样自然地定义样式。
  3. 部分和导入。Sass 允许在单独的文件中部分定义样式类,并将 Sass 文件导入到其他文件中。这类似于 Typescript 允许代码文件被导入,以便它们可以被重用。
  4. Mixin。这允许将一组样式聚合到一个抽象样式(@mixin 指令)中,可能包含参数。要使用 mixin,可以使用特殊语法来包含/重用定义(@include)。
  5. 继承。继承允许使用 @extend 指令重用样式。这意味着你可以定义一些样式并在应用程序的其他地方重用和扩展它们。
  6. 运算符。这些允许从常量或变量计算值。运算符的示例是算术运算符。

        Ionic 使用一种称为 SCSS(Sassy CSS)的语法,由 .scss 文件扩展名指示。这不是最初的 Sass 语法,称为 plain Sass(由 .sass 文件扩展名指示)。主要区别在于 SCSS 使用带有“{”和“}”符号的嵌套语法,这与你在其他编程语言中熟悉的语法相同,而 SASS 是基于缩进的语法。两种语法都是有效的,可以完全相互转换,并且上述导入和文件包含功能可以将一种代码加载到另一种代码中。

        Sass 的重用功能允许将主题打包成一组 Sass 文件,并集成到 ionic 应用程序中。我们已经注意到,在 ionic 网站上有很多主题出售,每个主题都作为一组 Sass 文件分发。这些通过 src/theming/ 目录中的变量.scss 主题文件集成到 ionic 应用程序中。此文件包含一系列 Sass @import 语句,并允许变量声明,以便将各种样式集成到应用程序中。

  • 30
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yamai Yuzuru

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值