一、程序架构
模块:用来将应用中 不同的部分 组织成 一个Angular框架可以理解的单元。
组件:是anguler应用的基本构建块,带有业务逻辑和数据的Html。
服务:用来封装可重用的业务逻辑
指令:允许你向Html元素增加自定义行为
自定义指令
二、命令行工具
npm install -g @angular/cli
ng new name --routing
ng g component 组件名
ng g servicr 服务名
ng g pipe 管道名
angular cli命令
三、模块
app.module.ts文件
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
import { FooterComponent } from './footer/footer.component';
import { IndexComponent } from './index/index.component';
import { AboutComponent } from './about/about.component';
import { CartComponent } from './cart/cart.component';
import { ListComponent } from './list/list.component';
import { NavSimpleComponent } from './nav-simple/nav-simple.component';
import { NavComponent } from './nav/nav.component';
import { ResultComponent } from './result/result.component';
import { UserCenterComponent } from './user-center/user-center.component';
import { UserLoginComponent } from './user-login/user-login.component';
import { UserRegisterComponent } from './user-register/user-register.component';
import { UserPassResetComponent } from './user-pass-reset/user-pass-reset.component';
import {RouterModule, Routes} from '@angular/router';
import { ContentComponent } from './content/content.component';
const routeConfig: Routes = [
{path: '', component: IndexComponent},
{path: 'user-login', component: UserLoginComponent},
{path: 'user-register', component: UserRegisterComponent}
];
// 模块装饰器
@NgModule({
// 只能放组件、指令、管道
declarations: [ //声明
AppComponent,
HeaderComponent,
FooterComponent,
IndexComponent,
AboutComponent,
CartComponent,
ListComponent,
NavSimpleComponent,
NavComponent,
ResultComponent,
UserCenterComponent,
UserLoginComponent,
UserRegisterComponent,
UserPassResetComponent,
ContentComponent,
],
// typeScript类 模块要正常运行依赖的其他模块
// 引入模块后,在自定义的组件中引入他定义的组件、指令、服务
imports: [
BrowserModule, // 浏览器模块
RouterModule.forRoot(routeConfig) // 处理表单模块
// HTTP模块
],
// 服务
providers: [],
// 模块主组件
bootstrap: [AppComponent]
})
// typeScript类 模块
export class AppModule { }
四、组件
app.components.ts文件
// 组件
import { Component } from '@angular/core';
// 组件元数据装饰器
@Component({
// 装饰器属性是元数据
// 通过 调用
selector: 'app-root',
// 组件内容。html文件作为组件模板;用户看到的内容
templateUrl: './app.component.html',
// 组件模板用到的样式
styleUrls: ['./app.component.css']
})
// 控制器;与模板相关的所有属性和方法;与页面相关的逻辑
export class AppComponent {
title = 'wds';
}
// 数据绑定:模板和控制器联系起来
// {{}}
// 属相绑定
// 事件绑定
// 双向绑定
五、angular应用是如何启动的
angular启动加载页面
index.html文件
会在index.html中寻找启动模块指定的主组件对应的css选择器(selector)
angular启动加载脚本
main.ts文件
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)
.catch(err => console.log(err));
六、angular应用中如何引用第三方类库
第三方类库安装到本地
引入项目,修改angular.json中"scripts"和"styles"
库的类型定义文件也要安装 npm install @types/库名 --save-dev
七、路由
1、路由基础知识
2、应用位置
3、app-routing.module.ts文件
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './...';
import { ProductComponent } from './...';
const routes: Routes = [
// 需要注意 path中没有 /
{
path: '',
component: HomeComponent
},
{
path: 'product',
component: ProductComponent
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
routerLink
// 注意 /开头表示找主组件;没有/表示找子组件
// 参数是数组 方便传入参数
主页
商品详情
router
在路由时传递数据
在查询参数中传递数据(queryParams)
// /product?id=1
商品详情
private productId: number;
constructor (private routeInfo: ActivatedRoute){}
toProductDetails () {
this.router.navigate(['/product']);
}
ngOnInit () {
this.productId = this.routeInfo.snapshot.queryParams['id']
}
在路由路径中传递数据(path)
// /product?id=1
商品详情
{
path: 'product/:id',
component: ProductComponent
}
private productId: number;
constructor (private routeInfo: ActivatedRoute){}
toProductDetails () {
this.router.navigate(['/product']);
}
ngOnInit () {
// 参数订阅 RXJS语法 自己到自己也会刷数据
this.routeInfo.params.subscribe((params:Params) => this.productId = params['id'])
// 参数快照 自己到自己不会刷数据 原因组件没有再次被创建,ngOnInit方法没有再次被调用
this.productId = this.routeInfo.snapshot.Params['id']
}
在路由配置中传递数据
4、重定向路由
{path:'',redirectTo:'/home',pathMath:'full'}
5、子路由
// HomeComponent组件对应的html中有
{
path: '',
component: HomeComponent,
children:[
{
path: '',
component: XxxComponpath: ''
},
{
path: 'yyy',
component: YyyComponpath: ''
}
]
}
6、辅助路由
{
path: 'home',
component: HomeComponent,
},
{
path: 'product',
component: ProductComponent,
},
{
path: 'xxx',
component: "XxxComponent",
outlet:'aux'
},
{
path: 'yyy',
component: "YyyComponent",
outlet:'aux'
}
Xxx
Yyy
7、路由守卫
应用场景
路由守卫
CanActivate
CanDeactivate
resolve
进入路由前,读取商品信息。带着信息进入商品组件,直接渲染数据
八、依赖注入
1、依赖注入模式化解决问题
控制反转是将代码的依赖控制权从代码的内部转到代码的外部,
实现控制反转的手段是依赖注入。
控制反转侧重描述目的。
2、依赖注入模式的好处
松耦合方式编写代码,可测性,可重用性更高。
如何实现依赖注入的,注入器,提供器
提供器
提供器作用域规则
1、声明在模块中,模块中所有组件可见。
2、声明在组件中,当前组件和子组件可见,其他组件不可见。
3、当具有相同的token时,声明在组件中的注入器会覆盖声明在模块中的注入器。
4、优先声明在模块中。
@Injectable()别的服务注入到这个服务中。
useFactory
注入器的层级关系
提供器注册到注入器上
九、组件间通信
父子组件间通信
1、输入属性
在子组件中
单向数据绑定,子组件数据改变不会影响父组件
输出属性
在子组件中
中间人模式
兄弟组件,利用父组件中间人
没有共同父子件,利用可注入的服务作为中间人。
组件生命周期
红色调用一次(一定被调用),绿色调用多次(也可能不被调用)
constructor
一定被调用,只调用一次
ngOnChanges
前置知识:首先理解可变对象和不可变对象
可变对象:字符串
不可变对象:对象
父组件初始化或者修改子组件不可变对象的输入属性的时候被调用;如果没有输入属性(@input)ngOnChanges()方法永远不会被调用
ngOnInit
组件用到输入属性,逻辑一定写到 ngOnInit()中,因为输入属性在ngOnChanges后才有值
ngDoCheck
属性改变、事件(包括点击),整个组件树的的ngDoCheck()都会被调用,default 。还有onPush
变更检测策略
有变化,就会调用组件树所有的ngDoCheck()方法
ngAfterViewInit ngAfterViewchecked
模板本地变量@ViewChild()
分别是在控制器中调用子组件方法,和在模板中调用子组件方法
ngAfterViewInit()组件视图初始化完毕被调用一次
有变化,ngAfterViewCHecked()组件的视图变更检测完毕被调用,整个组件树的ngAfterViewCHecked()方法都会被调用
注意,组件视图被更新完毕后在改变属性,会触发异常,解决方法setTimeout()
ngAfterContentInit ngAfterContentchecked
九、数据绑定、响应式编程、管道
数据绑定(默认数据绑定是单向的)
事件绑定
注意:事件可以是浏览器默认事件,也可以是自定义事件
DOM属性绑定
前置知识
插值表达式===DOM属性绑定
HTML属性和DOM属性的差别
优先使用DOM属性绑定
第一行DOM属性(变,指定当前值),第二行HTML属性(不变,指定初始值,初始化DOM属性)
特殊属性
总结
注意:浏览器会保持DOM和UI同步;DOM属性改变自动触发UI
HTML属性绑定
九、表单
1、HTML表单
两种表单的不同
2、angular的模板式表单
ngNoForm
为form自动添加ngForm ngModel
ngModelGroup
模板表单示例
3、angular的相应式表单(数据模型通过指令连接HTML)
第一步、创建数据模型
formControl
formGroup: 是多个formControl的集合 <{}>
formArray:和formGroup类似,但有length属性,代表可增长的 字段集合formControl<[]>
响应式表单类 数据模型的实例
响应式表单指令
第二列是使用属性绑定,
第三列是使用属性的名字连接数据模型和DOM的,
不能通过模板本地变量引用创建的实例
formControl只能用在formGroup外部使用
示例
示例
FormBuilder重构代码
formGroup
formControl
表单校验
angular校验器;其实就是简单的方法
如何检验模板式表单
自带校验器
自定义校验器
如何校验响应式表单
hasError()
getError()
get()
valid/invalid 有效/无效
touch/untouched 获取焦点/没有焦点
pristine/dirty 质朴/脏 : 值从来没变过/被改变过
类似valid;all的都true,form才是true
pending 等待,未决定
angular根据不同状态,自动增加不同样式不同样式
十、组件生命周期(九个)
生命周期钩子
ngOnChanges钩子
变更检测机制,刷新不可变对象(字符串),调用ngOnChanges钩子 ;不刷新可变对象(对象属性),不调用ngOnChanges钩子
十一、绑定
差值表达式和属性绑定是一个东西
HTML属性和DOM属性
十二、动画
https://easings.net/
http://cubic-bezier.com