Angular 7 笔记(一)整体概述
说明:本博客为个人学习笔记,部分内容引用来自官方文档 Angular ,部分内容为个人总结和心得
整体概述
Angular(区别于AngularJS)是目前比较火的前端框架,和传统常见的前端框架不同的是Angular最新版本基于Typescript实现,提供了端到端的前端能力,包括桌面程序与移动端的开发实现等。下面基于官方文档对整体架构做一个概述。
Angular 中的模块NgModule
Angular 的基本构造块是 模块(NgModule),它为组件(component)提供了编译的上下文环境。 NgModule 会把相关的代码收集到一些功能集中。Angular 应用就是由一组 NgModule 定义出的。 应用至少会有一个用于引导应用的根模块,通常还会有很多特性模块。以下是一个模块的定义:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeroesComponent } from './heroes/heroes.component';
import {FormsModule} from "@angular/forms";
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
@NgModule({
declarations: [
AppComponent,
HeroesComponent,
HeroDetailComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
正如我们看到的,我们在应用的根下定义了一个名称为AppModule的类,同时我们通过装饰器@NgModule来声明这个模块。NgModule 可以将其组件和一组相关代码(如服务)关联起来,形成功能单元。每个 Angular 应用都有一个根模块,通常命名为 AppModule
。根模块提供了用来启动应用的引导机制。 一个应用通常会包含很多功能模块。
装饰器是一些用于修饰 JavaScript 类的函数。Angular 定义了许多装饰器,这些装饰器会把一些特定种类的元数据附加到类上,以便 Angular 了解这些这些类的含义以及该如何使用它们。
组件Component
每个 Angular 应用都至少有一个组件,也就是根组件,它会把组件树和页面中的 DOM 连接起来。 每个组件都会定义一个类,其中包含应用的数据和逻辑,并与一个 HTML 模板相关联,该模板定义了一个供目标环境下显示的视图。@Component()
装饰器表明紧随它的那个类是一个组件,并提供模板和该组件专属的元数据。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'angular-tour-of-heroes';
}
如上我们定义了一个名称为APPComponent的组件,这个组件我们在刚才的模块声明中也看到了它,它也是由一个装饰器@Component的装饰器来声明,装饰器包含三个部分,分别是selector、templateUrl、styleUrls。其中selector是CSS选择器,是与模板(HTML)中的标签对应的(#占位)。templateUrl定义了这个组件对应的模板所在的位置,同理styleUrls对应的是样式表的位置。
模板、指令和数据绑定
模板会把 HTML 和 Angular 的标记(markup)组合起来,这些标记可以在 HTML 元素显示出来之前修改它们。 模板中的指令会提供程序逻辑,而绑定标记会把你应用中的数据和 DOM 连接在一起。 有两种类型的数据绑定:
事件绑定 :让你的应用可以通过更新应用的数据来响应目标环境下的用户输入。
属性绑定 : 让你将从应用数据中计算出来的值插入到 HTML 中。
在视图显示出来之前,Angular 会先根据你的应用数据和逻辑来运行模板中的指令并解析绑定表达式,以修改 HTML 元素和 DOM。 Angular 支持双向数据绑定,这意味着 DOM 中发生的变化(比如用户的选择)同样可以反映回你的程序数据中。
你的模板也可以用管道转换要显示的值以增强用户体验。比如,可以使用管道来显示适合用户所在地区的日期和货币格式。 Angular 为一些通用的转换提供了预定义管道,你还可以定义自己的管道。
Angular中的服务 Service
Angular的服务(service)给我们提供了一种与组件解耦的方式,正如我们上面看到的,组件负责整个模型与视图的交互,而服务负责业务逻辑与数据,这样做的好处是实现了视图和业务逻辑的解耦,有利于程序的维护和扩展。Angular 把组件和服务区分开,以提高模块性和复用性。 通过把组件中和视图有关的功能与其他类型的处理分离开,你可以让组件类更加精简、高效。
理想情况下,组件的工作只管用户体验,而不用顾及其它。 它应该提供用于数据绑定的属性和方法,以便作为视图(由模板渲染)和应用逻辑(通常包含一些模型的概念)的中介者。
组件应该把诸如从服务器获取数据、验证用户输入或直接往控制台中写日志等工作委托给各种服务。通过把各种处理任务定义到可注入的服务类中,你可以让它被任何组件使用。 通过在不同的环境中注入同一种服务的不同提供商,你还可以让你的应用更具适应性。
一个最简单的服务定义如下:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class HeroService {
constructor() { }
}
我们看到这个服务也是由装饰器来声明元数据(到处是装饰器),这个@Injectable() 的装饰器类似于我们后端Java中的@Service,来表明这个类是可进行依赖注入(DI)的(前端也开始玩这个东西现在),当然服务也可以依赖其他的服务。
如何注入服务
如下是一个服务注入的例子,我们看到在这个类的构造器constructor方法的参数中定义了一个 BackendService 的服务,Angular正是通过这种方式来将一个服务注入到服务或者组件中的。当 Angular 发现某个组件依赖某个服务时,它会首先检查是否该注入器中已经有了那个服务的任何现有实例。如果所请求的服务尚不存在,注入器就会使用以前注册的服务提供商来制作一个,并把它加入注入器中,然后把该服务返回给 Angular。当所有请求的服务已解析并返回时,Angular 可以用这些服务实例为参数,调用该组件的构造函数。
export class HeroService {
constructor(
private backend: BackendService) { }
}
总结
下图是Angular的架构概览图,。。。。解释后补,现在没有理解透