Angular核心概念一览表(持续更新中2020.07.10)

1,246 阅读5分钟

装饰器

类级别

@Component()
@Directive()
@Pipe()
@Injectable()
@NgModule()

字段级别

@Input 
@Output

NgModule

中小型项目中ngModule往往只有一个,但在大型应用中,往往多个功能相关的ngModule

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
  imports:      [ BrowserModule ],
  providers:    [ Logger ],
  declarations: [ AppComponent ],
  exports:      [ AppComponent ],
  bootstrap:    [ AppComponent ],
  entryComponents:[],
})
export class AppModule { }

declarations

声明此模块中拥有的组件。譬如包括:components, directives, and pipes。

exports

declarations 的子集。导出,供其他模块引用。

imports

声明需要引入的其他模块组件。

providers

定义service,可以定义在全局或者组件级别。

bootstrap

指定根视图,仅根视图可配置此项。或者配置此项的组件,即为根视图,用来承载其余组件。渲染dom时候,会替换index.html 中app-root对应的元素。

entryComponents

需要按类型进行引导或动态加载组件,则必须将其显式添加

常用模块 路径 描述
BrowserModule @angular/platform-browser browser运行项目,必备之一,尤其web安全方面
CommonModule @angular/common 想使用NgIf,NgFor时,必须引入
FormsModule @angular/forms 想使用双向绑定NgModel时候
ReactiveFormsModule @angular/forms 想建立响应式应用
RouterModule @angular/router 想使用RouterLink,.forRoot()和.forChild()
HttpClientModule @angular/common/http 想发起http请求时

其中,BrowserModule,CommonModule在app.module.ts中至少引入一个。

Component

@Component({
 selector:    'app-hero-list',
 templateUrl: './hero-list.component.html',
 providers:  [ HeroService ]
})
export class HeroListComponent implements OnInit {}

selector -- 在html中使用的标签

模板

  • 方法一:直接定义html内容template,适用于内容较少
@Component({
  selector: 'lightswitch-comp',
  template: `
    <button (click)="clicked()">Click me!</button>
    <span>{{message}}</span>`
})
export class LightswitchComponent {}
  • 方法二:定义html文件路径templateUrl,适用于内容较多,扩展性好,还能发挥vscode等插件优势,推荐
@Component({
  selector:    'app-hero-list',
  templateUrl: './hero-list.component.html',
  providers:  [ HeroService ]
})
export class HeroListComponent implements OnInit {

providers -- 定义组件中依赖的其他业务逻辑

DI(Dependency Injection)- 依赖注入

创建服务

ng generate service xxx/xxxx

root级别, 整个应用都可用

@Injectable({
  providedIn: 'root',
})

Module级别

import { Injectable } from '@angular/core';
import { UserModule } from './user.module';

@Injectable({
  providedIn: UserModule,
})
export class UserService {
}

//or
import { NgModule } from '@angular/core';
import { UserService } from './user.service';

@NgModule({
  providers: [UserService],
})
export class UserModule {
}

Component级别(常用于延迟加载服务)

@Component({
  selector:    'app-hero-list',
  templateUrl: './hero-list.component.html',
  providers:  [ HeroService ]
})

服务注入过程

  • 创建组件时候,check构造方法依赖参数
  • 查询injector,是否存在对应的依赖服务
  • 有则直接使用;没有,注入对应的服务,如果服务不存在,抛出异常
  • 参数搜集完毕,调用构造方法,构造组件等实例

数据模型 -- js es6对象

数据显示

数值显示

{{}},进行属性绑定到html操作

<img src="{{imgSrc}}">

# or
<img [src]="imgSrc">

管道

{{ data | json | date:"MM/dd/yy" | uppercase  }}

内置

  • DatePipe
  • UpperCasePipe
  • LowerCasePipe,
  • CurrencyPipe,
  • PercentPipe

自定义管道


组件生命周期

onChanges

常用于父组件props传递数据,数据改变,组件视图修改

@Input、@Output

private _name:string ;
@Input
set name(val:string){
    this._name = val;
}
get name():string {
    return this._name;
}

private _address: string;
private _subject = new Subject<string>();
@Input
set address(val:string){
    this._address = val;
    this._subject.next(val);
}
get address():string {
    return this._address;
}

此种set方法:

  • 按照写的先后顺序,执行。
  • 可以用于解决onChages依赖数据,可用subject,触发业务逻辑

onInit

组件初始化,可用于http请求发起,紧随ngChanges第一次调用后,触发。

ngDoCheck

Developer's custom change detection.

ngAfterContentInit

After component content initialized.

ngAfterContentChecked

After every check of component content

ngAfterViewInit

After a component's views are initialized,常用于dom操作,譬如绘图需要svg存在

ngAfterViewChecked

After every check of a component's views

onDestory

页面切换,指令销毁前,需要处理的业务逻辑,或者性能优化,避免内存泄漏

在以下情况中,可能会失效:

  • Page Refresh
  • Tab Close
  • Browser Close
  • Navigation Away From Page
# 推荐如下做法,确保OnDestroy执行
@HostListener('window:beforeunload')
async ngOnDestroy() {
    if (this.myValueSub) {
        this.myValueSub.unsubscribe();
    }
  }

angular rxjs subscribe,如果不unsubscirbe,会出现内存泄漏

父子组件通信

@Input

 export class VoterComponent implements OnChanges {
     @Input()  name: string;
     //changes监听name变化,
     ngOnChanges(changes: SimpleChanges) {
        // changes.prop contains the old and the new value...
     }
     
 }

@Output

//output是一个事件,需要emit通知变动
export class VoterComponent implements OnChanges{
 @Input()  name: string;
 @Output() voted = new EventEmitter<IDataChage>();
 didVote = false;

 vote(agreed: IDataChage) {
   this.voted.emit(agreed);
   this.didVote = true;
 }
  //changes监听name变化,
 ngOnChanges(changes: SimpleChanges) {
   // changes.prop contains the old and the new value...
 }
}
//外层js接收如下:
dataChange(param:IDataChage):void{
   const {agreed} = param;
}

Angular状态管理NgRx

component样式处理

Emulated模式

  • 可以引用全局,不会对外暴露
  • 默认值
  • 采用该模式下,动态添加的组件,需要采用:host :ng-deep .xxx{ },生效样式

ShadowDom

  • 存在兼容性问题

none

  • 全局暴露
  • 存在模块样式互相影响的负面

js代码处理

  • 使用class="{{}}"
  • 使用[ngClass]="{'ClazzA':true}"
  • Render2
  const dom = this.iconRef.nativeElement;
  render2.addClass(dom,'clazzA')

指令

结构指令

影响界面元素布局

属性指令

影响界面元素属性、样式等

自定义指令

对数据进行转换处理,譬如 url的转义处理

Render2

主要用于替代Jquery,操作dom

HttpClient

Angular提供的模块HttpClient,发起Http请求,采用Observable模式,而非Promise

Rxjs

angular 响应式编程开发

单元测试

单元测试目的在于,提前发现,减少代码变动,业务功能的影响

编译模式

JIT (及时编译)

  • ng build 和 ng serve 命令启动系统时, 默认采用
  • 启动系统启动时候,编译template和转换ts为js,占用系统启动时间
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule);

AOT(ahead-of-time) 预编译

  • ngc 命令触发
  • 编译template和转换js,提前到构建时候

性能优化建议

lazy-loading

  • 系统分割为多个模块,模块采取懒加载方式,有助于JIT模式下加快下载、启动速度

webpack-treeShaking

  • 采用服务注入root级别,有利于webpack打包,treeshaking 无效code,减少包大小

参考文献:

Angular8

ngondestroy