本文系参考B站大地老师angular教学视频总结:

第一讲
⦁ angular前提准备:
⦁ typescript入门教程:https://www.itying.com/goods-905.html
⦁ angular环境搭建:
⦁ node.js
⦁ 若需要的话,安装淘宝镜像
⦁ Angular脚手架安装(只需安装一次):npm install -g @angular/cli (终端输入:ngv;检验angular脚手架是否安装成功)
⦁ 创建angular项目
⦁ 找到要创建项目的文件目录
⦁ 创建命令语句:ng new 项目名称(直接安装)/ ng new 项目名称 --skip-install (不安装依赖)
⦁ 运行项目:ng serve –open( ng serve 即可启动项目 --open是打开默认浏览器)

第二讲
1.angular目录讲解
⦁ app.modules.ts(引入组件)

2)创建组件命令:ng g component components/news (在components文件夹里面创建news组件) / ng g c components/news(简写)
3)绑定数据:在ts文件的NewComponent implements onInit中定义属性,使用属性在html文件中以双花括号的形式

第三讲:
⦁ 组件定义属性
⦁ 推荐写法: private 数据类型 = 值
注:声明属性的几种方式
Public 公有(默认)可以再当前类里面使用,也可以在类外面使用
Protected 保护类型 他只要在当前类和他的子类可以访问
Private 私有 只有在当前类才可以访问到这个属性
⦁ 组件中获取/修改属性:在函数中
⦁ 数据循环(显示索引):<li *ngFor=“let item of arr;let key=index”>{{item}}</li>
第四讲:
⦁ 引入本地图片:<img src=”assets/images/xxx.jpg” />
⦁ 引入远程图片:<img [src]=”pictureUrl” />
⦁ 组件内的条件判断:*ngIf=“flag”(没有else)
⦁ Switch条件判断:如下
<ul [ngSwitch] = “score”>
<li *ngSwitchCase=”1”>已支付</li>
<li *ngSwitchCase=”2”>未支付</li>
<li *ngSwitchCase=”3”>已取消</li>
<li *ngSwitchDefault >无效</li>
</ul>
⦁ 绑定属性:
<div [ngClass]=“{‘red’:flag,’blue’:!flag}”>
<div [ngStyle]=”{‘width’:’100px’}”>
⦁ 管道:例: {{todaty | data:‘yyyy-MM-dd HH:mm ss’}}
⦁ 事件/方法:
1)定义方法:写在与constructor函数平行的地方,方法之间不需要加逗号
2)执行方法:(click)= “getData()”
3)键盘事件:(keydown)= “keydown($event)“
Keydown(e){
Console.log(e.target) // 获取当前事件对象
Console.log(e.keyCode) // 获取当前事件对象的键盘码
}
⦁ 双向数据绑定(mvvm只是针对表单)
⦁ 首先在app.module.ts中引入 FormModule
Import {FormsModule} from ‘@angular/forms’
⦁ 引入某模块后,在app.module.ts中声明模块
⦁ 使用:<input [(ngModel)]=”keyWords“ />
4)备注:[ ]表示绑定属性,( )表示绑定事件

第七讲
angular中的服务
⦁ 创建服务命令:ng g service 服务名称
创建服务到指定目录下:ng g service services/storage(在app的services文件夹下面创建一个storage服务
⦁ 首先在app.module.ts中引入并声明服务;
⦁ 在组件中需要引用服务的话,需要在组件中再次引入,并且在constructor函数中初始化并通过this.xxx使用服务
⦁ 备注:组件可以调用服务,但是服务不能调用组件,服务与服务之间又可以相互调用;
第八讲:
angular中的dom操作
⦁ ngOnInit:组件和指令初始化完成的钩子函数,并不是真正的dom加载完成
⦁ ngAfterViewInit:视图加载完成的钩子函数
⦁ angular获取dom节点:
⦁ 在html中给节点命名:<div #myBox>获取dom节点</div>
⦁ 在ts中引入ViewChild,并在类里面使用ViewChild装饰器获取节点: @ViewChild('myBox') myBox: any;
⦁ 在ts的ngAfterViewInit生命周期中获取dom:this.myBox.nativeElement
⦁ ViewChild同样可以获取子组件实例,然后就可以调用子组件的方法
第九讲:
父子组件及组件通信
1.父传子:
1)父组件调用子组件的时候传入数据:
<app-header [newsMsg]="newsMsg" [newsFn]="newsFn" ></app-header>
⦁ 子组件引入import模块
import {Component, OnInit, Input} from '@angular/core';
⦁ 组件@input接收父组件传过来的数据
export class HeaderComponent implements OnInit {
@Input () newsMsg: any;
@Input () newsFn: any;
Constructor () {}
ngOnInit (): void {}
}
4)子组件使用父组件的数据: this. newsMsg; this. newsFn ()
2. 子传父: ViewChild(同angular获取dom节点的方式一致)
3.组件之间其他通信方法:(子组件触发父组件的方法,并向父组件传参)
1)子组件引入Output和EventEmitter
import {Component, OnInit, Input, Output, EventEmitter} from '@angular/core';
⦁ 子组件中实例化EventEmitter
@Output () private outer = new EventEmitter ();
3)子组件中写一个方法:通过EventEmitter对象outer实例广播数据
sendParent () {
this.outer.emit ('我要触发父组件方法')
}
以下是触发时机:
<button (click)="sendParent()">广播数据给父组件</button>
⦁ 父组件调用子组件的时候,定义接收事件,outer就是子组件的EventEmitter对象outer
<app-header (outer)="getHeader($event)"></app-header>
⦁ 父组件接受到数据就会调用组件的getHeader方法,此时能拿到子组件传递的数据。
getHeader(msg) {
alert( msg +'我是父组件中的方法')
}
备注:点击子组件中的button就能触发父组件中的getHeader方法,msg就是子组件传过来的值。
第十讲
angular的生命周期函数(8个):就是组件创建、组件更新、组件销毁的时候会触发的一系列的方法。
1.ngOnChanges ( ) : 当angular(重新)设置数据绑定输入属性时,(或者说是在父子组件传参发生改变时响应)。第一次触发在ngOnInit 之前。(若无父子组件之间传值,第一次不触发)
2.ngOnInit ( ): 在angular第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。(请求数据一般在这个周期中); 第一轮ngOnChanges ( )完成之后调用,只调用一次。
3.ngDocheck ( ): 检测,并在发生angular无法或不愿意自己检测的变化时做出反应(在此处检测数据,并自定义一些操作); 在每个angular变更检测周期中调用,ngOnChanges()和ngOnInit()之后。
4.ngAfterContentInit ( ):当把内容投影进组件之后调用(组件触发的时候调用)第一次ngDocheck()之后调用,只调用一次
5.ngAfterContentChecked ( ): 检测,每次完成被投影组件内容的变更检测之后调用,(组件完成后做一些自定义的操作)。
6.ngAfterViewInit():初始化完组件视图的变更检测之后调用,ngAfterViewInit()和每次ngAfterContentChecked ()之后调用
7.ngAfterViewChecked ():每次做完组件视图和子视图的变更检测之后调用。ngAfterViewInit()和每次ngAfterContentChecked()之后调用。
8.ngOnDestroy ():在angular销毁指令/组件之前调用
备注:页面加载各个钩子函数的执行顺序如下:
⦁ construct构造函数执行:除了使用简单的值对局部变量进行初始化之外,什么都不应该做
⦁ ngOnChanges执行:(若不涉及父子组件传值,该钩子函数不执行)
⦁ ngOnInit执行:一般在此请求数据
⦁ ngDocheck 执行,检测,或者做一些自定义的操作
⦁ ngAfterContentInit执行:把内容投影近组件之后
⦁ ngAfterContentCheck 执行:每次完成被投影组件内容的变更检测之后调用
⦁ ngAfterViewInit 执行:初始化完组件视图及其子视图之后(dom操作在此处)
⦁ ngAfterViewCheckd 执行:每次做完组件视图和子视图的变更检测之后调用
⦁ ngOnDestroy 执行:销毁组件时(可以在这里做一些保存的操作)

第十一讲:rxjs的简单介绍
⦁ 描述:RxJS是ReactiveX编成理念的JavaScript版本,来自微软,它是一种针对异步数据流的编程或者叫响应式扩展编程。
⦁ 常见的异步编程的几种方法:
⦁ 回调函数
⦁ 事件监听/发布订阅
⦁ Promise
⦁ Rxjs
定义方法:
import { Observable } from 'rxjs'
getRxjsData () {
return new Observable(observer=>{
setTimeout (() => {
let name = '王五'
observer.next (name)
// observer.error('失败')
},2000)
})
}
使用方法:
this.request.getRxjsData ().subscribe(data=> {
console.log(data)
})
 备注:从上述例子中可以看出promise和rxjs的用法基本相似,但其实rxjs比promise要强大很多:比如rxjs中可以中途撤回,可以发射多个值,提供了多种工具函数等。
1)rxjs使用之取消订阅:
let streem = this. request. getRxjsData();
let dele = streem. Subscribe (data=> {
console.log(data)
})
setTimeout (()=> {
dele. unsubscribe(); // 取消订阅
})

2)rxjs执行多次
定义方法:
getSetIntervalRxjsData() {
let count = 0
return new Observable(observer=>{
setInterval(()=>{
count++;
let name = '赵六'+count
observer.next(name)
// observer.error('失败')
},1000)
})
}
使用方法:
this.request.getSetIntervalRxjsData().subscribe(data=>{
console.log(data)
})
3)rxjs工具函数(filter)
例:map和filter
定义方法:
getSetIntervalRxjsNum() {
let count = 0
return new Observable(observer=>{
setInterval(()=>{
count++;
observer.next(count);
},1000)
})
}
执行方法:
import {map, filter} from 'rxjs/operators'
this.request.getSetIntervalRxjsNum().pipe( // 管道
filter((value)=>{ // 过滤
if(Number(value)%2 == 0){
return true
}
})
).subscribe(data=>{
console.log(data) // 只打印偶数
})
例:throttleTime(rxjs延迟执行)
import { Observable, fromEvent }from ‘rxjs’
import { map, filter, throttleTime } from ‘rxjs/operators’
var button = document.querySelector(‘button‘)
fromEvent (button, ‘click’). pipe (
throttleTime (1000)
). subscribe (() =>console.log(‘clicked’));

第十二讲:angular请求数据相关
1.angular内置模块根据不同需求引入不同请求模块
Angular获取服务器数据(get,post等)
在app.module.ts中引入HttpClientModule并注入
Import {HttpClientMoule} from ‘@angular/common/http’
Imports:[BrowserModule, HttpClientMoule ]
Jsonp获取服务器数据:(jsonp)
在app.module.ts中引入HttpClientModule、HttpClientJsonpMoudle并注入
Import {HttpClientMoule, HttpClientJsonpMoudle} from ‘@angular/common/http’
Imports:[BrowserModule, HttpClientMoule, HttpClientJsonpMoudle ]

请求数据
1) get方法,
在用到的地方引入HttpClient,并在构造函数声明
Import {HttpClient} from ‘@angular/common/http’
constructor (private http: HttpClient) {}

let api = ‘http://a.itying.com/api/productlist’,
this.http.get(api). subscribe (res => {
console.log(res)
})
2)post方法
在用到的地方需要引入HttpClient、HttpHeaders
import {HttpClient, HttpHeaders} from ‘@angular/common/http’
constructor (private http: HttpClient) {}
手动设置请求类型:
const httpOptions = {
headers: new HttpHeaders({‘Content-Type‘: ‘application/json’})
}
let api = ‘http://127.0.0.1:3000/doLogin’
this.http.post(api, {username: ‘张三‘,age: ‘20’},httpOptions).subscribe(res => {
console.log(res)
}
注:以上两种方法会存在跨域问题,需要服务器允许跨域
3)jsonp请求(服务器需要支持jsonp)
在用到的地方需要引入HttpClient、HttpHeaders
import {HttpClient, HttpHeaders} from ‘@angular/common/http’
constructor (private http: HttpClient) {}
let api = ‘http://127.0.0.1:3000/doLogin?callback=xxx’
let apis = ‘http://127.0.0.1:3000/doLogin?cb=xxx’(参数cb或者callback名由服务器定义)
this.http.jsonp (api,’callback’).subscribe(res => {}
2.外部服务器请求
1)安装插件:npm install axios –save
2)在封装服务的文件中(如:httpservice.service.ts)引入axios,并封装方法
Import axios from axios
例:axiosGet(api){
return newPromise((resolve,reject)=>{
axios.get(api).then(res=>{
resolve(res)
});
})
}
3)在app.module.ts中引入服务并申明
import {HttpserviceService} from ‘@/service/httpservice.service’
providers:[HttpserviceService]
4)在组件中使用服务:同样需要引入服务并申明,再在方法中使用
import {HttpserviceService} from ‘@/service/httpservice.service’
constructor (private httpService: HttpserviceService) {}
getAxiosData(){
let api=www.baidu.com
this.httpService.axiosGet(api).then(data=>{
console.log(data)
})
}

第十三讲
⦁ 路由就是根据不同的url地址,动态地让根组件挂载其他组件,来实现一个单页面应用
⦁ 配置路由
⦁ 创建项目的时候选择带路由
⦁ 在项目中创建组件
⦁ 在app.module.ts中引入组件并声明
⦁ 在app-routing.moudule.ts中引入组件并配置路由,配置写法如下:
const routes: Routes = [
{path: 'home', component: HomeComponent}
];
⦁ 在app.component.html中写上<router-outlet></router-outlet>,然后本地访问:
localhost:4200/home 就能显示home组件
⦁ 路由跳转
⦁ 使用routerLink跳转
<a [routerLink]="['/home']">首页</a>
⦁ 路由重定向(匹配默认路由):在routes: Routes中加上
{path: '**', redirectTo: 'home'},
⦁ routerlink选中路由增加默认样式(类名可自定义):
<a [routerLink]="['/home']" routerLinkActive="active">首页</a>
例:让选中a标签字体变成红色
.active {
color: red;
4.实际项目中根路由中会引入模块
第十四讲
路由跳转传值:
1.get传值(使用queryParams绑定,值为object类型):
1)传值:<a [routerLink]="[ '/newsContent']" [queryParams]="{aid: key}"> {{item}} </a>
2)接收:
(1)在接收的页面引入ActivedRoute :
ActivedRoute import {ActivatedRoute} from '@angular/router';
(2)在需要接收的页面初始化(在constructor函数中):
Constructor (private route: ActivatedRoute) {}
(3)获取路由参数:
this. route. queryParams. subscribe(data=>{
console.log(data) //data是一个object对象
})
2.动态路由
1)路由的定义与普通路由不同(在path后面绑定动态的参数名):
{path: 'NewsContent/:aid', component: NewsContentComponent},
2)传值(要传的动态参数就放在路径后面):
<a [routerLink]="[ '/NewsContent/', key]"> {{item}} </a>
⦁ 接收:
(1)在接收的页面引入ActivedRoute :
ActivedRoute import {ActivatedRoute} from '@angular/router';
(2)在需要接收的页面初始化(在constructor函数中):
Constructor (private route: ActivatedRoute) {}
(3)获取路由参数:
this. route. params. subscribe(data=>{
console.log(data) //data是一个object对象
})

3.get传值js跳转
⦁ 传值:
(1) 引入Router
import {Router, NavigationExtras} from '@angular/router';
⦁ 初始化Router实例
Constructor (private router: Router) {}
⦁ js跳转
goProDetail () {
let Params: NavigationExtras = {
queryParams: {'pid': 'wuhua'}
}
this. router. navigate(['/NewsContent/'], Params)
}
备注:Params不做NavigationExtras类型断言也可以传参,但是进行类型断言的写法更标准
2)接收:方法与a标签get传值路由跳转相同,这里就不赘述了

4.动态路由的js跳转
1)路由的定义与普通路由不同(在path后面绑定动态的参数名):
{path: 'NewsContent/:aid', component: NewsContentComponent},
2)传值(要传的动态参数就放在路径后面):
⦁ 引入Router
import {Router} from '@angular/router';
⦁ 初始化Router实例
Constructor (private router: Router) {}
⦁ js路由跳转
goProDetail () {
this.router.navigate(['/NewsContent/', '1234'])
}
⦁ 接收:方法与a标签动态路由相同,这里就不赘述了

第十五讲
Angular的嵌套路由:父子路由
⦁ 创建组件并引入到app-routing.module.ts(方法同普通路由一致)
⦁ 在父路由中的children中配置子路由,如下所示:

⦁ 使用子路由:
⦁ 在父路由的页面加上a标签或者在方法中用js跳转:
⦁ 在父路由页面使用<router-outlet></router-outlet>展示子路由
如下图所示:

第十七讲
Angular的内置模块以及自定义模块:
⦁ 内置模块:
1)@angular/core 核心模块
2)@angular/common 通用模块
3)@angular/forms 表单模块
4)@angular/http 网络模块
5)更多其他模块
2.自定义模块(项目较大/组件较多时会导致加载变慢,此时需要用到自定义模块)
1)创建模块和组件:
ng g module modules/user(在modules目录下面创建user模块)
简写:ng g m moudules/user
2)自定义模块要把需要暴露出去的组件exports出去
exports:[UserComponent], // 暴露组件,让其他模块可以使用
⦁ 根模块(app.module.ts)中需要引入并申明
import { UserModule } from './modules/user/user.module'
imports: [UserModule],
⦁ 根组件直接使用模块中暴露出来的组件
第十八讲:
路由模块实现懒加载
1).创建模块(自动生成当前模块的路由文件):
ng g m modules/user/ --routing
2)在当前模块的路由文件(user-routing.module.ts)中引入该模块的根组件,并配置当前模块的路由
import {userComponent} from ‘./user.component’ ;
const routes: Routes = [
{path:’’, component: userComponent}
]
3)在根模块(app.module)的路由文件(app-routing.module.ts)中设置模块的懒加载
const routes:Routes = [
{path: ‘user’, loadChildren:’./module/user/user.module#UserModule’}, // 写法1
{path:‘product’,loadChildren:()=>import(‘@pages/product/product.module’).then(m=>m.ProductModule)}, // 写法2
{path:‘**‘,redirectTo:’user’}
]

posted on 2020-12-04 10:18  固执的鱼wu  阅读(702)  评论(0)    收藏  举报