angular学习笔记

angular学习笔记

学习资源:官网

核心概念和架构

Angular 是一个用 HTML 和 TypeScript 构建客户端应用的平台与框架。 Angular 本身就是用 TypeScript 写成的。它将核心功能和可选功能作为一组 TypeScript 库进行实现,你可以把它们导入你的应用中。

angular 的基本构造模块是 NgModule,它为 component 提供编译的上下文环境。一个 angular 应用至少有一个根模块,通常还会有其他很多特性模块。

组件定义视图。视图是一组可见的屏幕元素。

组件使用服务。服务提供不与视图直接相关的功能,服务提供者能够作为依赖被注入到组件中。

模块、组件和服务都是使用装饰器的类,这些装饰器会标出它们的类型并提供元数据,以告知 Angular 该如何使用它们。

模块

概念

angular应用是模块化的,被称为 NgModule 。一个 NgModule 就是一个容器,用于存放一些内聚的代码块,这些代码块专注于某个应用领域、某个工作流或一组紧密相关的功能。 它可以包含一些组件、服务提供者或其它代码文件,其作用域由包含它们的 NgModule 定义。 它还可以导入一些由其它模块中导出的功能,并导出一些指定的功能供其它 NgModule 使用。

每个 angular 应用至少存在一个 NgModule,称为根模块(AppModule),位于 app.module.ts的文件中,引导这个文件就可以启动应用。

元数据

NgModule 是一个带有 @NgModule() 装饰器的类。@NgModule() 装饰器是一个函数,它接受一个元数据对象,该对象的属性用来描述这个模块。其中最重要的属性如下。

  • declarations(可声明对象表) —— 那些属于本 NgModule组件指令管道
  • exports(导出表) —— 那些能在其它模块的组件模板中使用的可声明对象的子集。
  • imports(导入表) —— 那些导出了模块中的组件模板所需的类的其它模块。
  • providers —— 本模块向全局服务中贡献的那些服务的创建器。 这些服务能被本应用中的任何部分使用。(你也可以在组件级别指定服务提供者,这通常是首选方式。)
  • bootstrap —— 应用的主视图,称为根组件。它是应用中所有其它视图的宿主。只有根模块才应该设置这个 bootstrap 属性。
与组件的关系

NgModule 为组件提供了上下文的编译环境,模块能包含任意多个组件。组件可以通过路由器加载,也可以通过模板创建。属于相同 NgModule 的组件会共享同一个编译上下文环境。

组件和模板共同定义视图,组件还可以包含视图层次结构,一个视图层次结构中可以混合使用由不同 NgModule 中的组件定义的视图。

NgModule和JavaScript的模块比较

NgModule 系统与 JavaScriptES2015)用来管理 JavaScript 对象的模块系统不同,而且也没有直接关联。 这两种模块系统不同但互补。你可以使用它们来共同编写你的应用。

JavaScript 中,每个文件是一个模块,文件中定义的所有对象都从属于那个模块。 通过 export 关键字,模块可以把它的某些对象声明为公共的。 其它 JavaScript 模块可以使用import 语句来访问这些公共对象。

组件

组件控制屏幕上被称为视图的区域。如导航栏,列表。

在类中定义组件的应用逻辑,为视图提供支持。 组件通过一些由属性和方法组成的 API 与视图交互。

组件元数据

组件的元数据告诉 Angular 到哪里获取它需要的主要构造块,以创建和展示这个组件及其视图。 具体来说,它把一个模板(无论是直接内联在代码中还是引用的外部文件)和该组件关联起来。 该组件及其模板,共同描述了一个视图

  • selector:是一个 CSS 选择器,它会告诉 Angular,一旦在模板 HTML 中找到了这个选择器对应的标签,就创建并插入该组件的一个实例。 比如,如果应用的 HTML 中包含 ``,Angular 就会在这些标签中插入一个 HeroListComponent 实例的视图。
  • templateUrl:该组件的 HTML 模板文件相对于这个组件文件的地址。 另外,你还可以用 template 属性的值来提供内联的 HTML 模板。 这个模板定义了该组件的宿主视图
  • providers:当前组件所需的服务提供者的一个数组。在这个例子中,它告诉 Angular 该如何提供一个 HeroService 实例,以获取要显示的英雄列表。
模板与视图

通过组件的配套模板来定义其视图。模板就是一种 HTML,它会告诉 Angular 如何渲染该组件。

视图通常会分层次进行组织,让你能以 UI 分区或页面为单位进行修改、显示或隐藏。 与组件直接关联的模板会定义该组件的宿主视图。该组件还可以定义一个带层次结构的视图,它包含一些内嵌的视图作为其它组件的宿主。

视图

模板语法

模板很像标准的 HTML,但是它还包含 Angular 的模板语法,这些模板语法可以根据你的应用逻辑、应用状态和 DOM 数据来修改这些 HTML。 你的模板可以使用数据绑定来协调应用和 DOM 中的数据,使用管道在显示出来之前对其进行转换,使用指令来把程序逻辑应用到要显示的内容上。

数据绑定

Angular 支持双向数据绑定,这是一种对模板中的各个部件与组件中的各个部件进行协调的机制。 往模板 HTML 中添加绑定标记可以告诉 Angular 该如何连接它们。

下图显示了数据绑定标记的四种形式。每种形式都有一个方向 —— 从组件到 DOM、从 DOM 到组件或双向。

数据绑定

<li>{{hero.name}}</li>
<app-hero-detail [hero]="selectedHero"></app-hero-detail>
<li (click)="selectHero(hero)"></li>
  • 这个插值在 `` 标签中显示组件的 hero.name 属性的值。
  • [hero]属性绑定把父组件 HeroListComponentselectedHero 的值传到子组件 HeroDetailComponenthero 属性中。
  • 当用户点击某个英雄的名字时,(click) 事件绑定会调用组件的 selectHero 方法。

双向数据绑定(主要用于模板驱动表单中),它会把属性绑定和事件绑定组合成一种单独的写法。下面这个来自 HeroDetailComponent 模板中的例子通过 ngModel 指令使用了双向数据绑定:

<input [(ngModel)]="hero.name">
管道

Angular 的管道可以让你在模板中声明显示值的转换逻辑。 带有 @Pipe 装饰器的类中会定义一个转换函数,用来把输入值转换成供视图显示用的输出值。

语法:{{interpolated_value | pipe_name}}

<!-- Default format: output 'Jun 15, 2015'-->

 <p>Today is {{today | date}}</p>

<!-- fullDate format: output 'Monday, June 15, 2015'-->

<p>The date is {{today | date:'fullDate'}}</p>

 <!-- shortTime format: output '9:43 AM'-->

 <p>The time is {{today | date:'shortTime'}}</p>
指令

指令分为结构型和属性型,它本质就是一个带有 @Directive() 装饰器的类。指令的元数据把它所装饰的指令类和一个 selector 关联起来,selector 用来把该指令插入到 HTML 中。

// 结构型指令
<li *ngFor="let hero of heroes"></li>
<app-hero-detail *ngIf="selectedHero"></app-hero-detail>

// 属性型指令
<input [(ngModel)]="hero.name">

服务与依赖注入

服务

服务的作用就是为了给组件提供功能的支持,如从服务器获取数据、验证用户输入或直接往控制台中写日志等。把它独立出来是为了提高模块性和复用性,组件的工作只用管与用户的交互和数据绑定的属性和方法。服务也可以依赖其它服务。

export class Logger {
  log(msg: any)   { console.log(msg); }
  error(msg: any) { console.error(msg); }
  warn(msg: any)  { console.warn(msg); }
}

export class HeroService {
  private heroes: Hero[] = [];

  constructor(
    private backend: BackendService,
    private logger: Logger) { }

  getHeroes() {
    this.backend.getAll(Hero).then( (heroes: Hero[]) => {
      this.logger.log(`Fetched ${heroes.length} heroes.`);
      this.heroes.push(...heroes); // fill cache
    });
    return this.heroes;
  }
}
依赖注入

依赖注入就是通过 angular 为你创建实例对象,让你能在组件中直接使用它们。服务的装饰器为 @Injectable() 。

  • 注入器是主要的机制。Angular 会在启动过程中为你创建全应用级注入器以及所需的其它注入器。不用自己创建注入器。
  • 该注入器会创建依赖、维护一个容器来管理这些依赖,并尽可能复用它们。
  • 提供者是一个对象,用来告诉注入器应该如何获取或创建依赖。

当 Angular 创建组件类的新实例时,它会通过查看该组件类的构造函数,来决定该组件依赖哪些服务或其它依赖项。

当 Angular 发现某个组件依赖某个服务时,它会首先检查是否该注入器中已经有了那个服务的任何现有实例。如果所请求的服务尚不存在,注入器就会使用以前注册的服务提供者来制作一个,并把它加入注入器中,然后把该服务返回给 Angular。

当所有请求的服务已解析并返回时,Angular 可以用这些服务实例为参数,调用该组件的构造函数。

提供服务

任何服务必须至少注册一个提供者,服务可以在自己的元数据中把自己注册为提供者,这样可以让自己随处可用。或者,也可以为特定的模块或组件注册提供者。要注册提供者,就要在服务的 @Injectable() 装饰器中提供它的元数据,或者在 @NgModule()@Component() 的元数据中。

通过 ng generate service 创建的服务,默认在 @Injectable() 装饰器中提供元数据来把它注册到根注入器中。当在根一级提供服务时,Angular 会创建一个单一的共享实例,并且把它注入到任何想要它的类中。这种在 @Injectable 元数据中注册提供者的方式还让 Angular 能够通过移除那些从未被用过的服务来优化大小。

架构

angular架构

Observables & RxJS


 上一篇
前端知识记录 前端知识记录
前端知识记录ECMAScript脚本语言规范 装饰器装饰器就是一个高阶函数(接收一个函数或返回一个函数至少满足一个条件) NodeJSNode.js® 是一个基于 Chrome V8 引擎 的 JavaScript 运行时。 并发模型与事件
2020-12-22
下一篇 
Go调用JS脚本 Go调用JS脚本
Go调用JS脚本Goja项目地址:goja 基本使用func main(){ vm := goja.New() val, err := vm.RunString(` 2+2 `) if err
2020-12-18
  目录