移动系统编程-Ionic 组件 (Ionic Components)

时间:2024-06-03 07:52:39

Ionic 组件

        到目前为止,我们已经使用 HTML 小部件为 HTML 页面提供数据输入、导航和其他服务。在移动设备上,网页小部件通常难以使用且不太美观。为了与我们的应用程序进行交互,ionic 提供了所谓的“组件”与用户进行交互。不要将术语“组件”与 Angular 组件混淆。正如你将看到的,ionic 组件将构成 Angular 组件的一部分。

        在 ionic 中有两种类型的组件:

  1. 可注入组件,有时仅称为 ionic 组件,使用 Angular 注入系统。这意味着它是一个提供一种或多种方法的对象,这些方法可以在 ionic 组件对象中访问。
  2. 声明性组件,它们是可以插入到 Angular 模板中的标签和属性。对于声明性组件,这意味着你不必在组件类中编写代码。

        Ionic 组件是为你的移动应用程序打包的小部件。它们将使你的应用程序更加美观和易用。理解 ionic 组件与 Angular 组件之间的区别很重要。Angular 组件是具有模板和代码的 Typescript 类。Ionic 组件是实现 ionic 应用程序某些用户交互部分的用户级小部件。Ionic 组件可能对应于 Angular 组件,因为正如你所学到的,Angular 组件控制用户可视区域的一部分。然而,ionic 组件也可能是在模板中由特殊定义的标签、属性和值组成的特定代码,这些代码自动实现或使用组件。

        为了演示可注入组件,考虑一个 ionic 操作表作为示例,它是一个显示在当前页面上方的 ionic 组件,向用户呈现一系列操作选项。当它被取消时,允许用户返回到基础页面。以下图片展示了添加到 tabs 应用程序主页的操作表。

重要更新:关于在 Ionic 7 应用程序中使用 ngModel

        这是关于在你的 Ionic 7 应用程序中使用 ngModel 的重要更新。Ionic 7.0.0 最近发布,新的版本中应用程序结构发生了重大变化。如果你使用的是 Ionic 的早期版本,请忽略此指南。要检查你机器上安装的 Ionic 版本,请在命令工具中使用以下命令:Ionic -v。如果安装的版本是 7.0.0 或更新版本,请注意,app.module.ts 文件将不再存在于你的应用程序的 app 文件夹中。为了在任何表单控件(例如输入文件、单选按钮、复选框等)中使用 ngModel 指令,你需要将 FormsModule 导入到组件文件中,而不是导入到 app.module.ts 文件中。请按照以下步骤将 FormsModule 导入到应用程序的组件中:

  1. 在组件文件中添加 import { FormsModule } from '@angular/forms';(例如 tab1.page.ts 文件)。
  2. 在同一组件文件中的 imports 中添加 FormsModule。例如:
@Component({
  selector: 'app-tab1',
  templateUrl: 'tab1.page.html',
  styleUrls: ['tab1.page.scss'],
  standalone: true,
  imports: [IonicModule, ExploreContainerComponent, FormsModule],
})

完成上述步骤后,你可以在同一组件的任何表单元素中使用 ngModel。

操作表 (Action Sheets)

        操作表是一个覆盖移动设备上当前可视区域的窗口。它用于向用户呈现一系列选项,用户可以选择其中一个选项,也可以取消覆盖。要取消覆盖,用户可以触摸操作表外部,或者(如果实现了)触摸覆盖上的取消选项。

        操作表从页面底部滚动显示其选项。未覆盖的页面变灰,因此用户知道他们不能与之交互。然后,用户必须选择呈现的选项之一。

        我们可以通过首先添加一个按钮来启动操作表将其添加到主页:

<ion-button (click)="doActionSheet()">Do Action Sheet</ion-button>

        然后将操作表模块添加到组件中,如下所示:

export class Tab1Page {
  constructor(private actionSheetCtrl: ActionSheetController) {}

  async doActionSheet() {
    let actionSheet = await this.actionSheetCtrl.create({
      header: 'Select an option',
      buttons: [
        {
          text: 'Think',
          role: 'destructive',
          handler: () => {
            console.log('Think clicked');
          }
        },
        {
          text: 'Eat',
          handler: () => {
            console.log('Eat clicked');
          }
        },
        {
          text: 'Cancel',
          role: 'cancel',
          handler: () => {
            console.log('Cancel clicked');
          }
        }
      ]
    });
    await actionSheet.present();
  }
}

        注意关于此操作表实现的以下几点:

  1. 我们必须从 @ionic/angular 导入 ActionSheetController 模块,以便使用它。(上述代码中未显示)
  2. 使用 Angular 依赖注入系统创建一个服务对象,我们可以通过它来显示操作表。首先创建操作表,然后使用对象的 present() 方法显示它。
  3. 操作表的描述作为参数传递给注入对象的 create() 方法。这是以 JavaScript 对象的形式传递的。
  4. 操作表的描述有两个部分,标题和按钮描述符数组。
  5. 每个按钮都有一个 text 属性和一个处理程序函数,当用户点击按钮时执行。在本例中,我们只是将消息记录到控制台。
  6. 两个按钮有一个 role 属性。这些是样式用来显示不同按钮属性的标志。在上述示例中,我们没有添加样式来更改这些。
  7. doActionSheet() 方法实现为异步方法。这允许延迟渲染操作表。从 ionic 版本 4 开始,操作表和其他控件返回 promises,这需要使用 await 来完成 promise。

        大多数 ionic 组件的格式类似。在下面的章节中,我们将看到许多这些组件。我们还将看到声明性组件,在下一节中有三个用于导航的声明性组件。

        如上所述,要使用操作表,我们将操作表描述传递给操作表控制器,使用其 create() 方法。一旦创建了操作表对象,我们使用 present() 成员函数显示它。控制器实现为一个注入组件,注入到页面组件中。在描述中,我们定义了操作表上每个按钮的角色。

参考文档

https://ionicframework.com/docs/components/

ion-action-sheet: Action Sheet Dialog for iOS and Android

警报 (Alerts)

        下一个组件是 ionic 警报。你可能已经在基本的 JavaScript 和其他 GUI 框架中遇到过这些警报,在这些框架中它们可能实现为打包的对话框。Ionic 将警报打包为一个可注入组件,并注入到将启动警报的页面中。

        你可以创建许多类型的警报,例如:

  • 基本警报 – 打印消息和一个确定按钮
  • 多按钮警报 – 打印消息和多个按钮(例如“确定”、“取消”按钮)
  • 提示 – 输入一个或多个文本项和按钮
  • 单选 – 显示一系列选项,带有单选选择和按钮
  • 复选框 – 显示一系列可选选项和按钮

        这些处理大多数情况下你希望显示信息或从用户那里收集简单信息,而不需要在新页面上编写复杂的表单。你也不局限于“确定”和“取消”按钮,可以实现任意多个按钮。你可以在警报配置中更改按钮的标签。所有组件都可以使用样式更改按钮、文本、单选按钮和复选框的外观。

        你可以在警报中放置的内容有限。你可以有一个或多个文本输入的警报、一个带有单选按钮的警报或一个带有复选框的警报。然而,你不能混合它们。

        文档中不太清楚的一点是如何访问在文本字段、单选按钮或复选框中输入的数据。这可以通过在处理程序参数中选择输入字段的 name 属性来访问。例如,以下警报的名称为 field1,可以在“确定”按钮的处理程序中通过选择传递给处理程序的参数中的 name 进行访问。

async presentAlert() {
  const alert = await this.alertContrl.create({
    header: 'Text input',
    inputs: [
      {
        name: 'field1',
        type: 'text',
      }
    ],
    buttons: [
      {
        text: 'Cancel',
        handler: () => {}
      },
      {
        text: 'OK',
        handler: (data) => {
          this.textInput = data.field1;
        }
      }
    ]
  });
  await alert.present();
}

参考文档

ion-alert: Ionic Alert Buttons with Custom Message Prompts

按钮 (Buttons)

        Ionic 按钮是用于在 ionic 应用程序中轻松包含不同形状和颜色按钮的集合。基本的 ionic 按钮使用 ion-button 属性声明,例如:

<ion-button>basic</ion-button>

        然后添加属性以选择不同的样式。

        第一个样式是通过 color 属性和 ionic 样式类选择按钮的颜色:default, light, dark, secondary, danger。这些样式是预定义的,但可以更改每种颜色。例如,以下按钮定义选择“danger”颜色。

<ion-button color="danger">Danger</ion-button>

        我们还可以通过使用 ionic 属性选择按钮的形状:

  • block – 拉伸显示器的全宽度
  • full – 全宽度并去除任何角
  • round – 按钮两端圆角

        我们可以指定大小:

  • small
  • 默认值(未指定大小)为中等大小
  • large

        我们还可以指定几种显示样式:

  • outline – 只绘制按钮的轮廓并带有彩色文本
  • clear – 只显示彩色文本,但整个按钮区域可以点击/触摸

        在下面的活动中我们将看到所有这些。

        我们还可以混合所有这些属性,例如:

<ion-button color="danger" size="small" shape="round" fill="outline">mixed</ion-button>

        最后,我们可以通过在按钮定义内部添加一个额外的标签来向按钮添加图标,例如:

<ion-button>
  <ion-icon name="train"></ion-icon>
  Click me
</ion-button>

        一旦我们有了一个图标,我们可以通过向 <ion-button> 标签添加 slot 属性来指定它在按钮图标分配区域中的显示位置。选项是:

  • start – 将图标放在按钮文本的左侧
  • end – 将图标放在按钮文本的右侧
  • icon-only – 将其放在图标区域的中间,不显示文本

        请注意,这些属性不仅指定将图标放置在文本的哪一侧。它会调整图标位置,在按钮边缘和图标与文本之间留出相等的空间。

        在下面的活动中有所有这些选项的示例。

参考文档

ion-button: Style Buttons with Custom CSS Properties

输入字段 (Input Fields)

        Ionic 输入字段是显示给用户以输入文本数据的文本输入字段。它们有多种格式,但都以类似的方式接受文本。<ion-input> 标签用于定义一个 ionic 输入区域,并接受 HTML <input> 标签接受的所有选项。它还可以与 <ion-label> 标签一起使用,有几种选项可以显示标签和文本字段。

        ionic <ion-input> 标签有几个独特的选项,可以在设备模拟器中最好地展示。标签可以显示在文本字段内,用户点击时浮动在文本字段上方,还有其他几种你可能在移动应用程序中见过的排列。

        如果标签与输入字段背景相同,则可能难以看到交互。下面的活动要求你实现每种类型的输入字段,以便你能看到标签与输入字段之间的交互。

参考文档

        阅读输入字段文档:

ion-input: Custom Input With Styling and CSS Properties

列表 (Lists)

        你应该已经看到过 <ion-list> 标签如何在你的 ionic 应用程序中引入一系列元素。你的活动应该在应用程序中保留一个包含图标和描述的页面。

        可以通过向 <ion-list> 标签添加一个属性来指定列表的两个整体选项:

  • lines="full" – 每个列表项之间的线条
  • lines="none" – 没有列表项之间的线条
  • lines="inset" – 线条延伸到插入宽度
  • inset="true" – 在列表的外部添加一个边距(左侧和右侧)

        列表可以由一系列 <ion-item> 标签组成,尽管可以使用其他元素。这些指定了每个列表项的内容。我们还可以引入列表分隔符 <ion-item-divider>,通过在列表中插入特定格式的文本来分隔长列表。我们还可以使用 <ion-list-header> 标签在列表的第一个元素插入标题。

        列表中的各个项目可以采取多种形式。我们可以像在按钮中那样引入一个图标,使每个列表元素以图标开头。我们还可以向列表引入其他元素,并且具有多行元素。我们还可以拥有列表交互元素,例如在阅读中看到的滑动元素。

        列表是展示类似数据集合的好方法。这意味着可以使用 Angular 运算符如 *ngFor 属性从声明在页面组件中的数组加载列表。你将在下面的活动中看到这些示例。

参考文档

        阅读 ionic 列表文档:

ion-list: Item List View Component for iOS and Android Apps

菜单 (Menus)

        Ionic 菜单是在当前屏幕顶部滑出选项菜单的事件,例如按钮点击,或者可以从显示区域的左侧或右侧拖出。在克隆的侧边菜单启动应用程序中,有一个按钮“切换”菜单从左侧滑出。

        菜单的一种常见用法是将一个列表放在其中,供用户选择选项。例如,克隆的启动应用程序的菜单定义如下:

<ion-menu>
  <ion-header>
    <ion-toolbar>
      <ion-title>Menu</ion-title>
    </ion-toolbar>
  </ion-header>

  <ion-content>
    <ion-list>
      <ion-menu-toggle auto-hide="false" *ngFor="let p of appPages">
        <ion-item [routerDirection]="'root'" [routerLink]="[p.url]">
          <ion-icon slot="start" [name]="p.icon"></ion-icon>
          <ion-label>
            {{p.title}}
          </ion-label>
        </ion-item>
      </ion-menu-toggle>
    </ion-list>
  </ion-content>
</ion-menu>

        此代码演示了菜单的几个方面:

  1. 菜单可以有一个由 <ion-header> 标签定义的标题。在此示例中,标题中放置了一个工具栏。
  2. <ion-content> 标签定义选项的显示方式,在本例中是一个 ionic 列表(参见前一节)。上面的列表内容定义为由 *ngFor 属性生成的 <ion-menu-toggle> 元素。

        一旦定义了菜单,我们可以通过多种方式启动它。在侧边菜单启动应用程序中,菜单由模板中定义的按钮启动:

<ion-buttons slot="start">
  <ion-menu-button>Toggle Menu</ion-menu-button>
</ion-buttons>

        有时我们希望从组件代码切换菜单。这需要使用可注入组件 MenuController,该组件具有操作菜单的方法:

  • openMenu(), closeMenu()toggleMenu() – 操作当前菜单

        还可以有多个菜单,但一次只能有一个是活动的。MenuController 提供在菜单之间切换的方法。你可以使用 menuid 属性为菜单提供标识符,例如 menuid="myMenu"

        另一个选项是使菜单从屏幕的右侧出现。这可以通过在 <ion-menu> 标签中使用 side="end" 属性来指定。请注意,side="start" 是默认值。

参考文档

        阅读菜单文档:

ion-menu: API Framework Docs for Types of Menu Components

        接下来,我们看一下单选按钮。

单选组 (Radio Groups)

        单选按钮类似于许多组件,只不过它们组合在一起执行单选操作,当选择一个新项目时,之前选择的项目会被取消选择。

        单选组经常放置在列表中。然而,单选按钮的分组是通过 <ion-radio-group> 标签执行的。例如,以下代码组成一个单选按钮组。

<ion-list>
  <ion-radio-group>
    <ion-list-header>
      Select your favourite colour
    </ion-list-header>
    <ion-item>
      <ion-label>Red</ion-label>
      <ion-radio value="red" [(ngModel)]="favColour"></ion-radio>
    </ion-item>
    <!-- more colours added here -->
  </ion-radio-group>
</ion-list>

        单选按钮还可以被禁用,使其不参与单选选择过程。这通过将 <ion-radio>disabled 属性设置为 true 来实现。

        我们还可以使用 <radio> 标签中的 checked 属性选择初始单选按钮。

活动 18(教程活动)

        阅读单选按钮文档:

ion-radio: Radio Component for iOS and Android

        为单选按钮添加另一个页面到你的应用程序。

  1. 将上述颜色单选列表添加到你的应用程序。
  2. 在单选按钮后添加一个段落以显示所选颜色。这将使用上述示例中的 ngModel 值。在红色按钮单选中添加 checked 属性。
  3. 禁用其中一个单选按钮以查看效果(不是已选中的)。

        接下来,我们看一下 ionic 范围和切换组件。

范围和切换 (Ranges and Toggles)

        Ionic 范围组件呈现一个滑块,用户可以用它在给定范围的值中选择一个值。通常通过将变量分配给 ngModel 来直接更改页面组件中的变量。

        以下是一个范围组件的简单示例:

<ion-range [(ngModel)]="value">
  <ion-icon slot="start" size="small" name="train"></ion-icon>
  <ion-icon slot="end" size="large" name="train"></ion-icon>
</ion-range>

        此示例提供了一个范围从 0 到 100,左侧有一个小火车图标,右侧有一个大火车图标。所选值在定义模板的组件中定义的 value 属性中维护。如果不指定限制,这些具有默认值 0 和 100。

        我们要更改的第一件事是范围的最小和最大值。这些通过在 <ion-range> 标签中设置 minmax 属性来设置。

        你可以使用文本而不是图标,通过使用 <ion-label> 标签代替 <ion-icon> 标签。它们必须具有 slot="start"slot="end" 属性以指定放置标签的侧。

        默认情况下,范围控制器具有平滑滚动。你可以通过指定 step 属性定义刻度之间的距离来使它们具有“刻度”。如果未指定步长,则默认值为 1,通常会产生平滑滚动的效果,除非范围是少量值。如果以编程方式将值设置为刻度之间的值,显示将把选择器放在刻度之间。你可以通过向范围标签添加 snaps 属性使其移动到最近的刻度。

        你还可以使范围的左右两侧都可移动。这通过在范围中放置 dualknobs='true' 属性来实现。当这样做时,值将是一个复杂的 JavaScript 对象,具有两个属性:lowerupper,以指定选择的左右值。

        最小的范围组件是仅选择两个值,并且它有自己的组件外观和标签。它被称为切换组件。通常用作“开”和“关”状态之间的开关。切换可以在一个标签中定义,例如:

<ion-item>
  <ion-label>Hungry?</ion-label>
  <ion-toggle [(ngModel)]="hungry"></ion-toggle>
</ion-item>

        我们将其显示在列表项中,因为切换通常需要一个描述,以便用户知道开关的用途。在这种情况下,hungry 变量将被声明为布尔变量,并根据切换的状态分配 truefalse

        我们还可以通过将 checked 属性的值更改为 true 来更改初始状态。我们还可以禁用切换,使用户无法更改它,通过将 disabled 属性更改为 true

参考文档

        阅读范围文档:

ion-range: Range Slider Knob Controls with Labels

ion-toggle: Custom Toggle Button for Ionic Applications

段 (Segments)

        段是一种带有标签的显示类型。它们的操作与其他几个 ionic 组件类似但外观不同。在这里我们将看一下段,但你会发现这些想法很容易转化为其他组件。

        总体思路是设置一个保存页面名称的标题。Ionic 然后根据顶部标签选择的显示信息使用 Angular 分配在模板中选择显示信息。以下是一个段标题示例。

<div padding>
  <ion-segment [(ngModel)]="pet">
    <ion-segment-button value="kittens">
      Kittens
    </ion-segment-button>
    <ion-segment-button value="puppies">
      Puppies
    </ion-segment-button>
  </ion-segment>
</div>

        这是两个可选择显示的标题。请注意此模板代码的以下几点:

  1. <ion-segment> 标签放在 <div> 标签内。在这种情况下,<div> 标签在两个可选择区域的中间引入填充。你也可以将段放在标题、内容或表单中。
  2. <ion-segment> 标签使用 Angular 双向分配更新在组件中声明的 pet 变量。此变量将用于选择标题下方显示的信息。
  3. 声明了两个段按钮,用户可以点击/单击以选择显示的文本。<ion-segment-button> 标签定义按钮和要放在段变量中的值。

        这就是标题的全部内容。你可以添加任何按钮属性(见上文)以更改按钮的形式。

        然后我们需要声明按钮显示的数据。这可以使用标准 ngSwitch 属性的 <div> 标签来完成。对于上述段标题,我们可以定义两个页面如下,

<div [ngSwitch]="pet">
  <ion-list *ngSwitchCase="'puppies'">
    <ion-item>
      ...
    </ion-item>
    ... more list items
  </ion-list>
  <ion-list *ngSwitchCase="'kittens'">
    <ion-item>
      ...
    </ion-item>
    ... more list items
  </ion-list>
</div>

        这是标准的 Angular 切换代码。在这种情况下,切换选项放在 <ion-list> 标签中,因此为用户选择的每个段显示一个单独的列表。你可以使用列表以外的其他组件。

        下面的阅读中有更一般的示例,通过处理 ionChange 事件简单地在控制台上显示段之间的切换。上述代码仅展示了一种在应用程序中使用段的方法。

        你还将在下面的阅读中看到,我们可以通过赋值给 value 标签选择初始段或以编程方式选择新段。例如,在上面的标题示例中,我们可以通过以下方式初始选择“puppies”段:

<ion-segment [(ngModel)]="pet" value='puppies'>

        我们还可以使段可滚动。当有太多段按钮无法放入屏幕时,这很有用。我们可以通过在 <ion-segment> 标签中添加 scrollable 属性使段可滚动。