- angular 是一个重量级的框架,集成了构建客户端应用的全部功能,而 react 只是集成了构建页面的功能。
- 整个架构分三部分
- 模块 module — 用装饰器 @NgModule 标识,是功能的集合。
- declarations: 定义了该 NgModule 的组成部分:Components 、directives、pipe
- exports: module A 引入了 module B,则 module A declarations 中的 component 能使用 module B exports 的 component
- 组件 component — @Component
- 服务 service — @Injectable跨组件共享的数据/逻辑,服务要作为依赖注入到组件中。
- 模块 module — 用装饰器 @NgModule 标识,是功能的集合。
- 共享模块:设置模块级别需共享的组件/逻辑
- 创建共享模块命令 ng g m shared
- 创建共享模块组件 ng g c shared/components/layout
- 数据绑定:{{}} 通过插值表达式进行数据绑定
- 普通属性绑定:[两种方式的区别在于有些属性只能用 HTML 标记]
- Dom 对象属性
- HTML 标记属性
- class 属性:
<div [class.active]="flagBool">xxx</div>
<div [ngClass]="{'active': aBool, 'error': eBool}">xxx</div>
- style 属性:
<div [style.width]="'200px'">xxx</div>
<div [ngStyle]="{width: '200px'}">xxx</div>
获取原生 Dom 对象:
<button #btn (click)="onClick(btn)">xxx</button>
@ViewChild
<p #paragraph>xxx</p>
@ViewChild ("paragraph") paragraph: ElementRef<HTMLParagraphElement> | undefined
ngViewChild() { this.paragraph?.nativeElement}
@ViewChildren
<ul>
<li #item></li>
<li #item></li>
</ul>
@ViewChildren("item") items: QueryList<HTMLxxx> | undefined
ngViewChildren() {
this.items?.toArray()
}
内容投影 [剪切还是复制过去的]
<div class="heading">xxx</div>
<ng-content select=".heading"></ng-content>
// select 值对应类名
数据双向绑定,angular 数据双向绑定依赖于 @angular/forms 库,相关模块 FormsModule [(ngModule)]=”user”
- 全局样式
- 方式1: style.css 文件中引入 @import “~bootstrap/dist/css/…”
- 方式2: index.html 文件中引入
- 方式3: angular.json 文件中引入
指令 Directive
- 属性指令:修改外观 如 [hidden] 控制 dom 节点显隐
- 结构指令:*ngFor 相对应的是 key 属性,在 angular 中通过如下方式表示 key
trackBy:identity // trackBy 相当于 key identity 表示方法名
identity(index:number, item: list) {
return item.id
}
自定义指令
- ng g d
@Directive({
selector: "[appHover]"
})
export class HoverDirective implements AfterViewInit {
@Input("appHover") appHover: Options = {}
element: HTMLElement
constructor(private elementRef: ElementRef) {
this.element = this.elementRef.nativeElement
}
ngAfterViewInit() {
this.element.style.backgroundColor = this.appHover.bgColor || 'red'
}
// 为元素绑定事件
@HostListener("mouseenter") enter() {}
@HostListener("mouseleave") leave() {}
}
- ng g d
管道 pipe : 格式化组件模板数据
- date
- currenct
- uppercase
- json
- 组件生命周期
- 挂载阶段
- constructor: 载入 service
- ngOnInit:接收到输入属性 @Input
- ngAfterContentInit:内容投影初始渲染后
- ngAfterViewInit:组件视图渲染后
- 更新阶段
- ngOnChanges:输入属性改变时,优先于 ngOnInit 执行,且可以多次执行。存储的是发生变化的数据。
ngOnChanges(changes:SimpleChanges){ console.log(changes) }
- ngDoCheck:调试使用
- ngAfterContentChecked
- ngAfterViewChecked
- ngOnChanges:输入属性改变时,优先于 ngOnInit 执行,且可以多次执行。存储的是发生变化的数据。
- 卸载阶段
- ngOnDestory
- 挂载阶段
问题1: 内容投影 [剪切还是复制过去的]
结论:内容投影本质上是将要插入的内容从原先的位置移动到新的位置(先被移除再被插入到新的位置)
理由:html 代码渲染时,遇到 ng-content 时会调用一系列函数,最终是调用了一个 nativeAppendChild 方法,将元素插入到插槽。而 nativeAppendChild 方法本质上使用的 appendChild 方法,因此得到如上结论。
问题2: forChild VS forRoot
应用层面:forRoot是用在根模块加载路由配置,而forChild是用在子模块加载路由配置
相关链接:
angular 内容投影
appendChild 方法