angular企业开发笔记

1 组件相关

1.1 Angular中类的构造器

小括号可以说是这个类在实例化是便加载的成员变量[注意,不是new一个对象需要传参!!]
Ts构造器中所谓的参数严格意义上应该称为依赖,在小括号中注入,在大括号中进行逻辑处理

1.2 组件关系

1.2.1 父子组件

如果一个组件的模板中以html标记的形式调用了另一个组件模板,那么被调用的组件(整个组件)就是子组件
而调用者组件即为父组件

1.2.2 父子节点

在父组件标记中包含着子组件,这时浏览器渲染出的结果为父节点与子节点

1.3 组件生命周期

angular的每个组件在一定的生命周期都会提供一些业务接口,只要实现这些接口就可以在到达一定的时期时执行所重写的钩子函数
具体的钩子函数以及执行的时间顺序如下:
constructor -> ngOnChanges -> ngOnInit -> ngDoCheck -> ngAfterContentInit ->
ngAfterContentChecked -> ngAfterViewInit -> ngAfterViewChecked -> ngOnDestroy
各钩子函数的目的:

  1. ngOnChanges : 当组件初始输入属性值时会在ngOnInit之前执行一次,之后每当输入属性值发生变化时这个函数都会执行,而且不管变化的属性值多少,只要有变化,该
    函数都只执行一次
  2. ngOnInit: 在整个组件周期中只执行一次,初始化组件或指令,如果组件想要通过获取后台或远程服务器的数据来显示可以使用ngOnInit
  3. ngDoCheck: 主要用于调试,执行在每一个ngOnChanges之后,初次执行在ngOnInit之后
  4. ngAfterContentInit: 在angular将外部内容投影到组件视图之后响应
  5. ngAfterContentChecked: 外部内容投影更新后执行
  6. ngAfterViewInit: 在组件和子组件或包含在内的指令的视图初始化完成后执行
  7. ngAfterViewChecked: 组件视图更新后执行
  8. ngOnDestroy: 在angular 销毁组件或指令实例对象时执行,这个阶段可以unSubcribe一些可观察对象和脱离事件相应以防内存泄漏,主要释放资源

1.4 显示控制

1.4.1 ng-Content

使用场景:想要子Dom节点显示在指定的位置
占位符,又叫做组件插槽,标签类的自定义属性会被忽略,因为不会产生Dom元素,当组件模板中含多个ng-content时,可以使用select来匹配指定的元素进行显示
这里的匹配只匹配第一层即插槽之中的那一层,而包含一个div或者其他标签中是无法显示内容的

1.4.2 ng-Container

使用场景:需要显示一定量的内容但是不想要产生大量的Dom元素,或者当需要同时使用 ngIf 和 ngFor指令时(在同一个元素中使用这两个指令会报错)
有条件的内容投影(可用ngIf控制),可以使用 templateRefExp 来匹配模板ID(模板变量),使用context来匹配组件类中所提供的数据,可以使用ng-template投影context
中的数据,默认为implicit,ng-template可以在外部然后用ContentChild获取到实例再使用templateRefExp匹配

<ng-container *ngTemplateOutlet="templateRefExp; context: contextExp">ng-container>

例子:

<ng-container *ngTemplateOutlet="testID;context:myContext">ng-container>
<ng-template #testID let-displayValue="默认如果不指定键名为implicit,但显示其他值需要指定键名">{{ displayValue }}ng-template>
// .ts文件
contextExp = {$implicit:'value1',otherValue:'value2'}
1.4.3 ng-Template

等待其他元素召唤的内容显示,会产生Dom元素,ng-template会被angualr视作一个TemplatRef实例对象,如果想要在组件类中创建ng-template,可以先获取到装ng-template的
容器并转型为ViewTemplateRef,然后再使用createEmbeddedView()方法创建出一个个TemplateRef实例,这些实例会在模板上被渲染成ng-template显示出来,与createEmbeddedView
方法相似的还有一个createComponent方法,这个方法可以动态的创建组件ComponentRef,ng-template 不可以自主控制地显示里面的内容,必须让它地引用者来控制显示,ng-template
可以和ng-content联合使用
例子:

<ng-container #father>ng-container>
<ng-template #son let-impicit>{{ impicit }}ng-template>
embedContext = {$implicit:'embedimplicit',localvalue:'embedotherValue'};
  
  @ViewChild('test') 
  tmp!: TemplateRef

  @ViewChild('father',{read:ViewContainerRef})
  tmpFather!: ViewContainerRef

  ngAfterViewInit(): void {
    this.tmpFather.createEmbeddedView(this.tmp,this.embedContext)
  }

: 如果想要有条件的显示某块内容或多次显示某块内容,推荐使用ng-template而不推荐ng-content

1.5 @Input 与 @Output(父子组件之间通信)

这两个装饰器主要用来进行父子组件之间的通信
其中
@Input 修饰子类组件中的property,表示允许父类组件的数据流入  
===> 在子组件选择标记中绑定数据

@Output 也是在子类组件中修饰,表示可以向父类发送数据,被@Output修饰过的为Observable类  
===> 在父组件模板的子组件选择标记中绑定事件(数据)在父类组件中定义接受事件

 两个都是在子组件类中修饰,一个从外接收,另一个向外发送   

 两个都是在父组件模板中的子组件标记中绑定数据或事件的,@Output 是在父组件类中定义数据接收事件

1.6 数据绑定

1.6.1 [] , {{ }}的区别

官方一直推荐使用[]进行数据绑定,使用 [] 与{{}} 的唯一区别就是后者会将变量解析后再转化为字符串

1.6.2 动态绑定样式类(或者html属性)
  1. 兄弟类 如 class=“one two three” 这时想给组件加一个four 可以在相应的模板中加上[class]=“four”
  2. 孩子类 如 样式中是:
    .parent{
    .first{}
    .second{}
    }
    

这时相加一个.third{}可以在相应的模板中加上[parent.third]=“true”,这个true可以通过方法,也可以通过变量
angular企业开发笔记_第1张图片

1.6.3 HTML标记元素 与 Dom属性元素
  1. html标记仅仅是浏览器引擎渲染Dom节点的一种描述方法
  2. javaScrip(typeScript)获取到的都是Dom元素而不是html元素
  3. 获取Dom节点的属性只需要通过点运算符(因为它是该Dom对象的成员变量),而获取html属性需要通过getAttrbute()方法
  4. Dom属性为Property(是原生属性,不可人为添加), Html属性为Attribute(可以人为添加然后根据getAttribute方法获取)
1.6.4 NgModel

1.7 获取子组件节点 和 获取原生Dom

1.7.1 ContentChildren(ContentChild)

使用方法:

  1. 模板变量: 在调用父节点的模板中,找到父节点中的子节点上添加变量
  2. 业务逻辑: 在父节点的组件类中定义业务逻辑
  3. 获取结果: 获取的是子节点的组件实例对象

当在一个组件模板中调用另一个组件模板时如

@ContentChildren [@ContentChild同理]  
// 这里要明白Content Dom 和子组件调用的区别
// parent.compnent.html


// app.component.html

// 此时的Dom树为

在这里插入图片描述

  1. 当在App.component.html中使用一个组件的标记
    包住另一个组件的标记时如
// app.component.html



// 此时的Dom树为  

在这里插入图片描述

当一个child Element被加时,受@ContentChildren()
注解所修饰的QuerryList也会更新,这里强调的是Content 以及 Element
与子组件的调用完全不同,必须是某个模板标签包裹着另外的模板标签(子Element)
才会生效

1.7.2 ViewChildren(ViewChild)

ViewChild用来获取视图模板中与选择器匹配成功的的Dom,常和模板变量以及ElementRef联用,用来获取
模板中的原生dom
参数: selector|read|static
selector: 选择器,一般匹配内容为模板变量或者类名
read: 每个元素都有一个ElementRef和ViewContainerRef,ViewChild默认返回ElementRef
如果需要从获取的Dom中获取别的东西,需要通过read特殊指定
static: 是否静态,当设置为true时在定义的change 运行之前加载查询结果,设置为false时
在change运行之后加载查寻结果,默认为false

2 表单相关

2.1 FormControl

2.2 表单验证器(angular原生)

3 指令相关

3.1 Ng-* 系列指令(angular)

3.2 自定义指令

4 DI框架相关

4.1 多层依赖注入

4.1.1 @Option

@Option: angular会通过此注解将注入的服务认为是可执行服务,以至于当无法解析注入的服务时仅仅会返回null而不会报出错误

4.1.2 @SkipSelf

@SkipSelf: 当父子组件都使用相同的provider,但是不想使用子组件的provider而想使用父级注入器所提供的

4.1.3 @Self

@Self: 只在它自己组件类中的providers中加载依赖

4.2 依赖注入实现

当一个类要作为一个dependency提供出去时,需要使用@Injector装饰器装饰,我们只需要将依赖注册到消费者的构造器中,angular会自动创建依赖的实例对象
但是前提是必须要声明依赖提供者,需要在指令或组件的@Component装饰器通过provider声明

4.2.1 Injector类

用来获取依赖类的实例

4.2.2 Provider 依赖使用覆盖层
  1. root层: AppModule下的所有组件都可使用,声明root层时比较特殊,直接在@Injector装饰器中声明
  2. module层: 该module下的所有组件都可使用
  3. component层: 该组件以及该组件的所有子组件都可以使用
4.2.3 Provider 配置
@Component({
  selector: 'app-test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.css'],
  providers:[{provide: TestInjectorService, useClass:TestInjectorService}]
})

provide: 提供让angular DI框架解析的token来获取依赖实例,默认是类名

useClass: 在依赖注入时告诉DI 框架将useClass指定的类实例化,provide可以是基类名,然后使用指定扩展类使用扩展功能,如果依赖提供者本身也有自己的依赖
需要将提供者的依赖也声明在消费者的provider中

useExisting: 用一个新的token来代替已经存在的token ,其中provide所指出的token实际上使用的是useExisting指出的token,即第一个token是第二个token的别名

useFactory: 使用工厂方法返回实例对象

useValue: 使用静态值

forwardRef方法: 解决以下的问题

angular企业开发笔记_第2张图片

angular企业开发笔记_第3张图片

5 封装组件相关

5.1 封装组件的实现过程以及接口方法概述

5.1.1 实现ControlValueAccessor接口
interface ControlValueAccessor {
  // 向Dom Elelment写入一个新的值
  writeValue(obj: any): void
  // 当组件的control的值发生改变时注册被调用的回调函数
  registerOnChange(fn: any): void
  // 当组件的焦点离开(组件被触发过了)时注册被调用的回调函数
  registerOnTouched(fn: any): void
  setDisabledState(isDisabled: boolean)?: void
}
5.1.2 使用NgControl
5.1.3 使用NgModel

5.2 在封装组件时父子节点通过Provider相互关联

在项目中,parent 如何通过抽象类获取到子组件节点的?
@ContentChild/@ContentChildren的selector可以匹配到以下标识
而父组件也使用了ng-content占位符,所以说被包住的模板标记就是该组件的子组件
Any class with the @Component or @Directive decorator
A template reference variable as a string (e.g query with @ContentChild(‘cmp’))
Any provider defined in the child component tree of the current component (e.g. @ContentChild(SomeService) someService: SomeService)
Any provider defined through a string token (e.g. @ContentChild(‘someToken’) someTokenVal: any)
A TemplateRef (e.g. query with @ContentChild(TemplateRef) template;)
其实在项目中使用这两种方式都可以获取到子节点

 provide:'Child',useExisting:forwardRef(()=>ChildComponent)
 provide:Child,useExisting:forwardRef(()=>ChildComponent)

项目中子组件如何获取到父节点:

  1. 层次依赖注入机制: 子组件 -> 父组件 -> 模块 -> root
  2. 重写父类构造器
  3. @SkipSelf装饰器

5.3 封装组件的表单验证,手写表单验证器

6 NGRX相关

6.1 安装

安装配置@ngrx/shematics链接: https://ngrx.io/guide/schematics
注: 需要在angular.json 中配置,添加一项

"cli": {
    "defaultCollection": "@ngrx/schematics",
  }

6.2 CLI生成Store时参数解释

–module: 指定模块名,在该模块中的import选项中添加StoreModule
–statePath: State文件放置路径
–stateInterface: State 数据结构
–root: store也是以模块为单位的,当要生成的store属于根模块,要加上–root选项,否则便不需要加

6.3 NGRX中各文件的介绍

  1. 创建store时会生成一个index文件,其中有创建时定义的数据接口(类型),如果在创建reducer时指定了reducer选项,则可以将reducer中
    一个个小的状态接口都注册在index文件的大的状态接口中
  2. 创建action时会生成一个.action文件,在action中定义方法(包括参数),在reducer中实现具体逻辑,在组件中通过Store的dispatch方法调用
  3. 创建reducer时会生成一个.reducer文件,里面有这个reducer所可以控制的状态数据类型与初始值
  4. 创建selector时会生成一个.selector文件,通过定义selecttor可以获得相对应的store中的数据视图
    关于Selector,介绍两个重要的对象,一个是特征选择器,另一个是特征状态选择器
//指定要选择哪一个特征
export const selectFeature = (state:StateData) => state.countState;

/*
*特征选择其另外一种写法
export const selectFeature = createFeatureSelector(newReducerFeatureKey)
*/

//选择指定特征的状态
export const selectFeatureCount = createSelector(selectFeature,(state) => state.count)

6.4 更新中 。。。

6.5 更新中 。。。

6.6 更新中 。。。

6.7 更新中 。。。

7 RXJS相关

扩展

c-1 陌生的类

c-1.1 ElementRef: 一般在获取原生Dom时使用,是一种返回渲染Dom的包装器

Injector[abstract]

//Injector use
class Square {
  name = 'square';
}
// 配置Injector,创建注入器
const injector = Injector.create({providers: [{provide: Square, deps: []}]});

// 获取provider的实例
const shape: Square = injector.get(Square);

c-1.2 ControlValueAccessor: 实现绑定表单formControl的接口

c-2 陌生方法

  // Using `coerceBooleanProperty` allows for the disabled value of a button to be set as
  // `` instead of ``.
  // It also allows for a string to be passed like ``.
  @Input()
  get disabled() { return this._disabled; }
  set disabled(value: BooleanInput) {
    this._disabled = coerceBooleanProperty(value);
  }
  private _disabled = false;
  coerceBooleanProperty
  //只要指定了属性(无论是否赋值),都将转化为布尔值true
/**
 * ... 三点语法可以抽取数组中的数据,相当于将[]剥掉
 */
let arr = [1,2,3,4]
console.log(arr)
let brr = [true,"Alan",...arr]
console.log(brr)

//结果
PS C:\  node .\test.js
[ 1, 2, 3, 4 ]
[ true, 'Alan', 1, 2, 3, 4 ]

你可能感兴趣的:(angular.js,前端,javascript)