Augular笔记
Augular
Google开源的JavaScript的库web前端框架
诞生于2009年
软件安装
代码提示:Angular Snippets
中文:Chinese
环境搭建
ndoejs
node.js 稳定版本
node -v
npm -v
cnpm
建议安装一下cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm -v
安装 angular/cli 脚手架(只需要安装一次)
npm install -g @angular/cli
或者
cnpm install -g @angular/cli
测试脚手架
ng v
创建项目
打开cmd命令控制窗口,进入文件目录
可以先不安装路由,使用css即可
ng new 项目名称
ng new angulardemo
再次创建项目时,可以跳过安装依赖
ng new angulardemo --skip-install
安装依赖
npm i
或者
cnpm install
运行项目
ng serve --open
介绍
框架结构
app.module.ts
自定义组件
组件component
//创建组件,一个home组件
ng g component components/home
//app.module.ts 中加载
//1、引入
//2、加载
//app.component.html 中使用引用组件
<app-home></app-home>
图片资源
.ts 文件中
picUrl='https://xxxxx.png';
.html 文件中
//引用本地资源
<img src="assets/images/01.png" alt="收藏" />
//引用网络资源
<img [src]="picUrl" />
循环判断
for循环
<ol>
<li *ngFor="let val of items;let key=index;">
{{key}} --> {{val}}
</li>
</ol>
//key 是索引,val是值
if判断
//.ts 文件
flag : boolean = false;
//.html 文件
<div *ngIf="flag">
<img src="assets/images/01.png" />
</div>
<div *ngIf="!flag">
<img src="assets/images/01.png" />
</div>
ngSwicth
绑定属性
ngClass
ngClass
//动态改变样式, blue 样式是true red 样式是false
<div [ngClass]="{'blue':true,'red',false}">
ngClass演示
</div>
//根据 flag 改变样式
<div [ngClass]="{'orange':flag,'red',!flag}">
ngClass演示
</div>
ngStyle
ngStyle
//直接设置样式
<p [ngStyle]="{'color':'blue'}">
我是一个标签
</p>
//使用表达式赋值
attr:string = 'red';
<p [ngStyle]="{'color' : attr}">
我是一个标签
</p>
管道
在模板里面调用一个方法
大小写转换
大小写转换
<p>{{str | uppercase}}</p> //转换成大写
<p>{{str | lowercase}}</p> //转换成小写
日期格式转换(常用)
日期格式转换
<p>{{today | date:'yyyy-MM-dd HH:mm:ss'}}</p>
小数位数
小数位数
//接收的参数格式为 {最少整数位数}.{最少小数位数}-{最多小数位数}
<p>{{ p | number:'1.2-4'}}</p>
JavaScript 对象序列化
JavaScript 对象序列化
<p>{{ {name : 'semlinker'} | json }}</p>
//output: {"name" : "semlinker"}
slice
slice
<p>{{ 'semlinker' | slice:0:3 }}</p>
//output: sem
管道链
管道链
<p>{{ 'semlinker' | slice:0:3 | uppercase }}</p>
//output: SEM
自定义管道
自定义管道
使用@Pipe 装饰器定义 Pipe 的 metadata信息,如 Pipe 的名称 - 即 name 属性
实现 PipeTransform 接口中定义的 transform 方法
1.1 WelcomePipe 定义
import {Pipe, PipeTransform} from '@angular/core';
[@Pipe](/user/Pipe)({name: 'welcome'})
export class WelcomePipe implements PipeTransform {
transform(value: string): string{
if(!value) return value;
if(typeof value !== 'string'){
throw new Error('Invalid pipe argument for WelconePipe')
}
return "Welcome to " + value;
}
}
1.2 WelcomePipe使用
<div>
<p ngNonBindablee>{{ 'semlinker' | welcome }} </p>
<p>{{ 'semlinker' | welcome }} </p> //output: Welcome to semlinker
</div>
2.1 RepeatPipe 定义
import {Pipe, PipeTransform} from '@angular/core';
[@Pipe](/user/Pipe)({name: 'repeat'})
export class RepeatPipe implements PipeTransform {
transform(value: any, times: number){
return value.repeat(times);
}
}
RepeatPipe使用
<div>
<p ngNonBindable>{{ 'lo' | repeat:3 }}</p>
<p>{{ 'lo' | repeat:3 }}</p>
//output: lololo
</div>
事件
(click)
// .ts
myrun(){
alert('自定义方法')
}
// .html文件
<button (click)="myrun()" > 执行事件</button>
(keydown)(keyup)
******普通方法******
// .ts
keyDown(){
console.log('自定义deydown方法');
}
// .html文件
<input type="text" (keydown)="keyDown()" ></input>
******获取对象******
// .ts
keyDown(e){
console.log('自定义deydown方法' + e.keyCode);
e.target.value //获取 input 里面的值
}
// .html文件,传入事件对象
<input type="text" (keydown)="keyDown($event)" ></input>
获取事件对象
runEvent(event){
var dom:any = event.target;
dom.style.color="red";
}
<button (click)="runEvent($event)">执行方法获取事件对象</button>
(change)
//
双向数据绑定(MVVM)
这里只是针对表单
首先:app.module.ts 引入 FormsModule
import { FormsModule } from '@angular/forms';
keywords:string = '这是默认值';
<input type="text" [(ngModel)]='keywords'></input> {{keywords}}
表单
dom操作(angular里不推荐)
双向数据绑定(推荐)
先引入 FormsModule
[(ngModule)]="functionxxxx"
input type="text"
input type="radio"
select
<select name="city" id="city" [(ngModule)]="peopleInfo.city">
<option [value]="item" *ngFor="let item of peopleInfo.cityList">{{tiem}}</option>
</select>
input type="checkbox"
textarea
完整toDoList
服务
可以提供公共方法
服务和组件 关系说明
组件之间不能相互调用,保持独立
服务之间可以相互调用
组件 -> 服务 ,组件可以调用服务中的方法
服务 -> 组件,服务不能调用组件的东西
使用方法
创建命名
ng g service services/storage
app.modeule.ts 中引入
在使用的组件中引用 服务对象
- import引入
- constructor 构造方法中 初始化,也称注入
使用方法,调用服务中的get方法:
let s = this.storage.get()
服务,封装功能
dom操作
方法一:原生 js 操作dom
在 augular 中, ngOnInit() 方法不是 dom 加载完成的方法, 存在 ng 语法的 dom ,会获取不到
实现 原生js 获取dom 要 在 ngAfterViewInit() 方法中
方法二:ViewChild 操作 dom
-
模板中给dom起一个名字
<div #myBox> 我是一个dom节点 </div>
-
在业务逻辑里面引入 ViewChild
import { Component, OnInit, ViewChild} form '@angular/core';
-
通过viewchild获取dom节点
这个要卸载类里面
@ViewChild('myBox') myBox:any;
-
在生命周期函数 ngAfterViewInit() 中获取到
this.myBox.nativeElement
ViewChild 另一个作用,父组件调用子组件
使用方法如同 viewchild 操作 dom 方法一样
执行 CSS3 动画
null。。。
父子组件、组件之间的通信
父组件 给 子组件传值(@input)
父组件不仅可以给子组件传递简单的数据,还可以把自己的方法以及整个父组件传给子组件
子组件可以 获取父组件的数据、执行父组件的方法
父 -> 子,传数据
父 -> 子,传数据
-
父组件调用子组件的时候传入数据
<app-header [msg]="msg"></app-header>
-
子组件引入 input 模块
import { Component, OnInit, Input} form '@angular/core';
-
子组件中 @input 接收父组件传过来的数据
export class HeaderComponent implements OnInit{
@Input() msg:string
}
父 -> 子,传方法
父 -> 子,传方法
和传数据差不多
父 -> 子,传父组件
父 -> 子,传 整个父组件
在标签上 直接传入 this
子组件 给 父组件传值
方法一:父组件 通过 @viewchild 主动获取子组件
父组件可以 获取子组件的数据、执行子组件的方法
-
调用子组件给子组件定义一个名称
-
引入 viewchild
-
3
-
父
-
父组件接收到数据会调用自己的 runParent 方法,这个时候就能拿到子组件 的数据
方法二:子组件 通过 @Output 触发父组件的方法
- 子组件引入 Output 和 EventEmitter
-
子组件中实例化 EventEmitter
-
子组件通过 EventEmitter 对象 outer 实例广播数据
-
父组件调用子组件的时候,定义接收事件 outer 就是子组件的 eventfmitter对象outer
-
父组件 监听 outer ,会触发 父组件自己的 run 方法
非父子组件:
方法一:LocalStorage
方法二:通过 服务
生命周期函数
8个 函数
Rxjs 介绍
参考手册: https://www.npmjs.com/package/rxjs
中文手册: https://cn.rx.js.org/
RxJS 是 ReactiveX 编程理念的 JavaScript版本。ReactiveX 来自微软,它是一种针对异步数据流的编程。简单来说,它将一切数据,包括HTTP请求,DOM事件或者普通数据等包装成流的形式,然后用强大丰富的操作符对流进行处理,使你能以同步编程的方式处理异步数据,并组合不同的操作符来轻松优雅的实现功能。
常见异步编程的几种方法
回调函数
1、回调函数
- 外部调用
//传入回调函数 data,获得request服务中 getCallbackData 方法
this.request.getCallbackData((data)=>{
console.log(data)
})
- 实现
//服务中,实现getCallbackData方法
getCallbackData(cb){
setTimeout(()=>{
var username='张三';
//返回 username
cb(username);
//延时 1秒执行 setTimeout 里面的内容
}, 1000)
}
事件监听、发布订阅
2、事件监听、发布订阅
promise 获取异步数据
3、promise 获取异步数据
se6 规范提供promise方法,获取异步信息
- 外部调用
//调用 request 服务中的getPromiseData方法
var promiseData=this.request.getPromiseData();
//promise 提供的 then 关键字
promiseData.then((data)=>{
console.log(data);
})
- 实现
getPromiseData(){
//成功返回resolve,失败返回reject。也可以不写 reject
return new Promise((resolve,reject)=>{
setTimeout(()=>{
var username='张三';
resolve(username);
},1000)
})
}
Rxjs 获取异步数据
4、Rxjs 获取异步数据,第三方模块
-
准备
首先需要引入模块
import { Observable } from 'rxjs';
-
外部调用
//调用 request 服务中的 getRxjsData 方法
var rxjsData = request.getRxjsData();
rxjsData.subscribe((data)=>{
console.log(data);
})
//形式2:调用
stream.subscribe(value=>console.log(value));
- 实现
//引入
import { Observable } from 'rxjs';
getRxjsData(){
return new Observable(observable=>{
setTimeout(()=>{
//成功用 next
observable.next('observable timeout');
//失败用 error
observable.error('数据')
},1000);
})
}
//形式2:也可以这样接收 observable 的值
let stream = new Observable(observable=>{
setTimeout(()=>{
observable.next('observable timeout');
},1000);
});
return stream;
Rxjs相比promise有诸多优点
- 动作可以通过 unsubscribe() 方法中途撤回
- 发射多个值
- Rxjs提供了多种工具函数
- 等等......
setTimeout,延时执行。
setInterval,定时器。
Rxjs定时多次执行
let stream = new Observable<number>(observer=>{
let count = 0;
setInterval(()=>{
observer.next(count++);
},1000);
})
stream.subscribe(value=>console.log("TTTTT"+value));
Rxjs6.x 以上使用方法
filter:过滤筛选
map:对数据进行处理
var streamNum=this.request.getRxjsIntervalNum();
//在 pipe 管道中进行处理
streamNum.pipe(
filter((value)=>{
if(value%2==0){
return true;
}
}),
map((value)=>{
return value*value;
})
)
.subscribe((data)=>{
console.log(data);
})
数据交互
angular 5.x 以后 get、post 和服务器交互使用的是 HttpCilentModule 模块
1、在 app.module.ts 中引入 HttpCilentModule 并注入
import { HttpCilentModule } from '@angular/common/http';
imports: [
BrowserModule,
HttpCilentModele
]
get 请求数据
//在用到的地方引入 HttpCilent 并在构造函数声明
import { HttpCilent } from "@angular/common/http";
constructor(public http:HttpCilent){ }
//使用
var api = "http://a.itying.com/api/productlist"
this.http.get(api).subscribe(response => {
console.log(response);
})
post 提交数据
//在用到的地方引入 HttpCilent、HttpHeaders 并在构造函数声明 HttpCilent
import { HttpCilent,HttpHeaders } from "@angular/common/http";
constructor(public http:HttpCilent){ }
//使用
const httpOptions = {
headers: new HttpHeaders({'Content-Type':'application/json'})
};
var api = "http://127.0.0.1:3000/doLogin";
this.http.post(api,{username:'张三',age:'20'},httpOptions).subscribe(response => {
console.log(response);
})
jsonp 请求数据
1、在 app.module.ts 中引入 HttpCilentModule、HttpCilentJsonpModule 并注入
import { HttpCilentModule,HttpCilentJsonpModule } from '@angular/common/http';
imports: [
BrowserModule,
HttpCilentModele,
HttpCilentJsonpModule
]
//在用到的地方引入 HttpCilent 并在构造函数声明 HttpCilent
import { HttpCilent } from "@angular/common/http";
constructor(public http:HttpCilent){ }
// 使用 jsonp 请求数据
const httpOptions = {
headers: new HttpHeaders({'Content-Type':'application/json'})
};
var api = "http://a.itying.com/api/productlist";
this.http.jsonp(api,'callback').subscribe(response => {
console.log(response);
})
使用 第三方模块 axios 请求数据
1、安装 axios 模块
npm install axios --save
2、引入
import axios from 'axios';
3、使用
//可以先封装,也可以直接使用 axios.get 直接获取
axiosGet(api){
//使用 Promise 封装,也可以使用其他方法
return new Promise((resolve,reject) => {
axios.get(api)
.then(function (response){
console.log(response)
})
})
}
//调用封装的方法
getAxiosData(){
console.log('axios 获取数据');
let api="http://a.itying.com/api/productlist";
this.httpService.axiosGet(api).then((data)=>{
console.log(data)
})
}
路由
以前组件之间挂载,是靠手动在一个组件中挂载其他组件的。
路由就是根据 不同的 url 地址,动态的让根组件挂载其他组件
来实现一个单页面应用
使用路由
1、创建路由项目
选择yes, 创建带路由的项目
ng new angulardome --skip-install
2、创建组件
创建需要的组件,在 app 中注入
3、配置路由
把组件 加入 路由配置
4、前端页面调用
找到 app.component.html 根组件模板,配置 router-outlet 显示动态加载的路由
动态路由
敲入快捷键 ng-route 通过 routerLink 实现跳转
//这种写法 是 动态路由
<a [routerLink]="[ '/home' ]"> 首页 </a>
//这种写法 是 静态路由
<a routerLink='/home'> 首页 </a>
默认挂载的组件 ,在路由配置中
{
path: '**' , redirectTO 'home'
}
选择路由后,保持选择 状态
使用 routerLinkActive="active" ,active 名 可以随意写。
<a [routerLink]="[ '/home' ]" routerLinkActive="active"> 首页 </a>