Angular 是一个应用设计框架与开发平台,旨在创建高效而精致的单页面应用。
Angular 与 AngularJS
AngularJS” 专指 1.X 版本,而不带 “JS” 的 “Angular” 则专指版本2及更高版本。
Angular 和 AngularJS 之间的区别
- 在设计上,Angular 是 AngularJS 的完全重写
- Angular 没有“作用域”或控制器的概念,其架构中的主要角色是一些层次化的组件
- Angular 具有不同的表达式语法,主要是用 "[ ]" 来表示属性绑定,以及用 "( )" 来表示事件绑定
- 模块化 – 许多核心功能都已模块化
- Angular 建议使用 Microsoft 的 TypeScript 语言,该语言引入了如下特性:
- 静态类型,包括泛型
- 装饰器,语法上类似于注解
- TypeScript 是 ECMAScript 6 (ES6) 的超集,并且与 ECMAScript 5 (即 JavaScript) 向下兼容
- 动态加载
- 异步模板编译
- RxJS 提供了迭代式回调。RxJS 在状态可见性和调试方面有局限,不过可以使用诸如 ngReact 或 ngrx 之类的响应式第三方库来解决这些问题
- 支持 Angular Universal,它可以在服务器上运行 Angular 应用程序
Angular 组件
组件是构成应用的砖块。组件包括三个部分:带有 @Component()
装饰器的 TypeScript 类、HTML 模板和样式文件。@Component()
装饰器会指定如下 Angular 专属信息:
- 一个 CSS 选择器,用于定义如何在模板中使用组件。模板中与此选择器匹配的 HTML 元素将成为该组件的实例。
- 一个 HTML 模板,用于指示 Angular 如何渲染此组件
- 一组可选的 CSS 样式,用于定义模板中 HTML 元素的外观
下面是一个最小化的 Angular 组件。
import { Component } from '@angular/core';
@Component({
selector: 'hello-world',
template: `
<h2>Hello World</h2>
<p>This is my first component!</p>
`
})
export class HelloWorldComponent {
// The code in this class drives the component's behavior.
}
要使用此组件,请在模板中编写以下内容:
<hello-world></hello-world>
当 Angular 渲染此组件时,生成的 DOM 如下所示:
<hello-world>
<h2>Hello World</h2>
<p>This is my first component!</p>
</hello-world>
Angular 的组件模型提供了强大的封装能力和直观的应用结构。组件还能让你的应用更容易进行单元测试,并可以提高代码的整体可读性。
Angular 模板
每个组件都有一个 HTML 模板,用于声明该组件的渲染方式。你可以内联它或用文件路径定义此模板。
Angular 添加了一些语法元素以扩展 HTML,让你可以从组件中插入动态值。当组件的状态更改时,Angular 会自动更新已渲染的 DOM。此功能的应用之一是插入动态文本,如下例子所示。
<p>{{ message }}</p>
这里 message 的值来自组件类:
import { Component } from '@angular/core';
@Component ({
selector: 'hello-world-interpolation',
templateUrl: './hello-world-interpolation.component.html'
})
export class HelloWorldInterpolationComponent {
message = 'Hello, World!';
}
当应用加载组件及其模板时,用户将看到以下内容:
<p>Hello, World!</p>
注意这里所用的双花括号 —— 它们指示 Angular 对其中的内容进行插值。
Angular 还支持属性绑定,以帮助你设置 HTML 元素的 Property 和 Attribute 的值,并将这些值传给应用的展示逻辑。
<p
[id]="sayHelloId"
[style.color]="fontColor">
You can set my color in the component!
</p>
注意这里所用的方括号 —— 该语法表明你正在将 Property 或 Attribute 绑定到组件类中的值。
可以声明事件监听器来监听并响应用户的操作,比如按键、鼠标移动、单击和触摸等。你可以通过在圆括号中指定事件名称来声明一个事件监听器:
<button
type="button"
[disabled]="canClick"
(click)="sayMessage()">
Trigger alert message
</button>
前面的例子中调用了一个方法,该方法是在组件类中定义的:
sayMessage() { alert(this.message); }
以下是在 Angular 模板中插值和绑定的例子:
hello-world-bindings.component.ts:
实例
import { Component } from '@angular/core';
@Component ({
selector: 'hello-world-bindings',
templateUrl: './hello-world-bindings.component.html'
})
export class HelloWorldBindingsComponent {
fontColor = 'blue';
sayHelloId = 1;
canClick = false;
message = 'Hello, World';
sayMessage() {
alert(this.message);
}
}
hello-world-bindings.component.html:
实例
<button
type="button"
[disabled]="canClick"
(click)="sayMessage()">
Trigger alert message
</button>
<p
[id]="sayHelloId"
[style.color]="fontColor">
You can set my color in the component!
</p>
<p>My color is {{ fontColor }}</p>
可以用指令来为模板添加额外功能。Angular 中最常用的指令是 *ngIf
和 *ngFor
。你可以使用指令执行各种任务,比如动态修改 DOM 结构。你还可以用自定义指令来创建出色的用户体验。
以下代码是 *ngIf
指令的例子。
hello-world-ngif.component.ts:
实例
import { Component } from '@angular/core';
@Component({
selector: 'hello-world-ngif',
templateUrl: './hello-world-ngif.component.html'
})
export class HelloWorldNgIfComponent {
message = "I'm read only!";
canEdit = false;
onEditClick() {
this.canEdit = !this.canEdit;
if (this.canEdit) {
this.message = 'You can edit me!';
} else {
this.message = "I'm read only!";
}
}
}
hello-world-ngif.component.html:
实例
<h2>Hello World: ngIf!</h2>
<button type="button" (click)="onEditClick()">Make text editable!</button>
<div *ngIf="canEdit; else noEdit">
<p>You can edit the following paragraph.</p>
</div>
<ng-template #noEdit>
<p>The following paragraph is read only. Try clicking the button!</p>
</ng-template>
<p [contentEditable]="canEdit">{{ message }}</p>
Angular 的声明式模板使让可以将应用的逻辑和外观完全分开。模板基于标准 HTML,因此易于构建、维护和更新。
Angular 依赖注入
依赖注入让你可以声明 TypeScript 类的依赖项,而无需操心如何实例化它们,Angular 会为你处理这些琐事。这种设计模式能让你写出更加可测试、也更灵活的代码。
为了说明依赖注入的工作原理,请考虑以下例子。第一个文件 logger.service.ts
中定义了一个 Logger
类。它包含一个 writeCount
函数,该函数将一个数字记录到控制台。
实例
import { Injectable } from '@angular/core';
@Injectable({providedIn: 'root'})
export class Logger {
writeCount(count: number) {
console.warn(count);
}
}
接下来,hello-world-di.component.ts
文件中定义了一个 Angular 组件。该组件包含一个按钮,它会使用此 Logger 类的 writeCount
函数。要访问此功能,可通过向构造函数中添加 private logger: Logger
来把 Logger
服务注入到 HelloWorldDI
类中。
实例
import { Component } from '@angular/core';
import { Logger } from '../logger.service';
@Component({
selector: 'hello-world-di',
templateUrl: './hello-world-di.component.html'
})
export class HelloWorldDependencyInjectionComponent {
count = 0;
constructor(private logger: Logger) { }
onLogMe() {
this.logger.writeCount(this.count);
this.count++;
}
}
Angular CLI
Angular CLI 是开发 Angular 应用程序的最快、直接和推荐的方式。
常用命令:
命令 | 详情 |
---|---|
ng build | 把 Angular 应用编译到一个输出目录中。 |
ng serve | 构建你的应用并启动开发服务器,当有文件变化时就重新构建。 |
ng generate | 基于原理图(schematic)生成或修改某些文件。 |
ng test | 在指定的项目上运行单元测试。 |
ng e2e | 构建一个 Angular 应用并启动开发服务器,然后运行端到端测试。 |
分享笔记