开始我们的 Angular 待办事项应用
在这一点上,我们准备开始使用 Angular 创建待办事项列表应用程序。完成的应用程序将显示待办事项列表,并包括编辑、删除和添加功能。在本文中,您将了解应用程序的结构,并逐步了解如何显示待办事项的基本列表。
| 先决条件 | 熟悉核心 HTML、CSS 和 JavaScript 语言,了解 终端/命令行。 |
|---|---|
| 目标 | 创建基本应用程序结构,使其显示待办事项列表,并了解 Angular 的基本概念,例如组件结构、组件之间的数据共享以及循环内容创建。 |
待办事项应用程序结构
与任何 Web 应用程序一样,Angular 应用程序都以 index.html 作为入口点。index.html 实际上是应用程序的顶级 HTML 模板
<!doctype html>
<html lang="en">
<head>
<!-- ... -->
</head>
<body>
<app-root></app-root>
</body>
</html>
在 <body> 标签内,Angular 使用一个特殊元素 - <app-root> - 插入您的主组件,该组件又包含您创建的其他组件。通常,您不需要触碰 index.html,并且您主要专注于应用程序中称为组件的专门区域内的工作。
使用组件组织应用程序
组件是 Angular 应用程序的核心构建块。此待办事项应用程序有两个组件 - 一个组件作为应用程序的基础,另一个组件用于处理待办事项。
每个组件都由一个 TypeScript 类、HTML 和 CSS 组成。TypeScript 会转译或转换为 JavaScript,这意味着您的应用程序最终会以纯 JavaScript 形式呈现,但您可以方便地使用 TypeScript 的扩展功能和简化的语法。
使用 *ngIf 和 *ngFor 动态更改 UI
本教程还介绍了两个重要的 Angular 指令,用于动态更改 DOM 的结构。指令就像您可以在 HTML 中使用的命令,以影响应用程序中的更改。
本教程介绍的第一个指令是 Angular 的迭代器 *ngFor。*ngFor 可以根据数组中的项目动态创建 DOM 元素。
本教程中学习的第二个指令是 *ngIf。您可以使用 *ngIf 根据条件添加或删除 DOM 中的元素。例如,如果用户想要编辑待办事项列表中的项目,您可以为他们提供编辑项目的方法。如果他们不想编辑项目,您可以删除编辑界面。
在组件之间共享数据
在此待办事项应用程序中,您配置组件以共享数据。要向待办事项列表添加新项目,主组件必须将新项目发送到第二个组件。此第二个组件管理项目,并负责编辑、标记为已完成以及删除单个项目。
您可以使用称为 @Input() 和 @Output() 的特殊装饰器在 Angular 组件之间共享数据。您可以使用这些装饰器指定某些属性允许数据进入或离开组件。要使用 @Output(),您在一个组件中触发一个事件,以便另一个组件知道有数据可用。
定义项目
在 app 目录中,创建一个名为 item.ts 的新文件,内容如下
export interface Item {
description: string;
done: boolean;
}
您将在 稍后 使用此文件,但现在了解和记录您对 item 的认识是一个好时机。Item 接口创建了一个 item 对象模型,以便您的应用程序能够理解什么是 item。对于此待办事项列表,item 是一个具有描述并且可以标记为已完成的对象。
向 AppComponent 添加逻辑
现在您已经了解了什么是 item,您可以通过将一些项目添加到应用程序中来为应用程序提供一些项目。在 app.component.ts 中,将内容替换为以下内容
import { Component } from "@angular/core";
import { CommonModule } from "@angular/common";
@Component({
standalone: true,
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
imports: [CommonModule],
})
export class AppComponent {
componentTitle = "My To Do List";
filter: "all" | "active" | "done" = "all";
allItems = [
{ description: "eat", done: true },
{ description: "sleep", done: false },
{ description: "play", done: false },
{ description: "laugh", done: false },
];
get items() {
if (this.filter === "all") {
return this.allItems;
}
return this.allItems.filter((item) =>
this.filter === "done" ? item.done : !item.done
);
}
}
前两行是 JavaScript 导入。在本例中,它们正在导入 Angular 库。@Component() 装饰器指定了有关 AppComponent 的元数据。以下是一些有关我们正在使用的元数据的更多信息
-
standalone:描述组件是否需要 NgModule。当组件是独立组件时,您的应用程序将使用导入直接管理模板依赖项(组件、指令等)。 -
selector:告诉您在模板中用于放置此组件的 CSS 选择器。此处为'app-root'。在index.html中,在body标签内,Angular CLI 在生成您的应用程序时添加了<app-root></app-root>。您可以通过将组件选择器添加到其他组件的 HTML 模板中来以相同的方式使用所有组件选择器。 -
templateUrl:指定与此组件关联的 HTML 文件。此处为'./app.component.html', styleUrls:提供特定于此组件的样式的文件位置和名称。此处为'./app.component.css'。imports:允许您指定组件的依赖项,这些依赖项可以在其模板中使用。
filter 属性的类型为 union,这意味着 filter 可以具有 all、active 或 done 的值。使用 union 类型,如果您在分配给 filter 属性的值中输入错误,TypeScript 会通知您,以便您可以尽早捕获错误。本指南将在后续步骤中向您展示如何添加筛选功能,但您也可以使用筛选功能来显示所有项目的默认列表。
allItems 数组包含待办事项及其是否已完成。第一个项目 eat 的 done 值为 true。
getter get items() 在 filter 等于 all 时从 allItems 数组中检索项目。否则,get items() 将根据用户如何筛选视图返回已完成或未完成的项目。getter 还将数组的名称设置为 items,您将在下一节中使用它。
向 AppComponent 模板添加 HTML
要在浏览器中查看项目列表,请将 app.component.html 的内容替换为以下 HTML
<div class="main">
<h1>{{ componentTitle }}</h1>
<h2>What would you like to do today?</h2>
<ul>
<li *ngFor="let item of items">{{item.description}}</li>
</ul>
</div>
<li> 包含一个 *ngFor,这是一个内置的 Angular 指令,用于迭代 items 数组中的项目。对于每个项目,*ngFor 都会创建一个新的 <li>。包含 item.description 的双花括号指示 Angular 使用每个项目的描述文本填充每个 <li>。
在浏览器中,您应该会看到以下项目的列表
My To Do List What would you like to do today? * eat * sleep * play * laugh
向列表中添加项目
待办事项列表需要一种添加项目的方法,所以让我们开始吧。在 app.component.ts 中,在 allItems 数组之后向类添加以下方法
addItem(description: string) {
if (!description) return;
this.allItems.unshift({
description,
done: false
});
}
addItem() 方法获取用户提供的项目,并在用户单击“添加”按钮时将其添加到数组中。addItem() 方法使用数组方法 unshift() 将新项目添加到数组的开头和列表的顶部。您也可以使用 push(),它会将新项目添加到数组的末尾和列表的底部。
要使用 addItem() 方法,请编辑 AppComponent 模板中的 HTML。在 app.component.html 中,将 <h2> 替换为以下内容
<label for="addItemInput">What would you like to do today?</label>
<input
#newItem
placeholder="add an item"
(keyup.enter)="addItem(newItem.value); newItem.value = ''"
class="lg-text-input"
id="addItemInput" />
<button class="btn-primary" (click)="addItem(newItem.value)">Add</button>
在上面的 HTML 中,#newItem 是一个模板变量。在这种情况下,模板变量使用 <input> 元素作为其值。可以在组件模板的任何位置引用模板变量。
当用户在 <input> 字段中键入新项目并按 Enter 键时,addItem() 方法会将该值添加到 allItems 数组中。按 Enter 键还会将 <input> 的值重置为空字符串。模板变量 #newItem 用于访问模板中 <input> 元素的值。用户也可以单击“添加”按钮(调用相同的 addItem() 方法),而不是按 Enter 键。