使用Cli安装Angular项目但不导入对应依赖ng new 项目名 --skip-install
项目结构
ts文件中声明属性的方式
解析ts文件中定义的html代码段使用innerHTML属性,实例如下
msg = "这是一段测试
"
<p [innerHTML]="msg">p>
*ngSwitch条件判断语句
<ul [ngSwitch]="score">
<li *ngSwitchCase="1">已支付li>
<li *ngSwitchCase="2">订单已确认li>
<li *ngSwitchCase="3">已发货li>
<li *ngSwitchDefault>无效li>
ul>
属性[ngClass]/[ngStyle]
[ngClass]="{'class名':boolean类型,'class名':boolean类型}"
[ngStyle]="{'style名':'style值'}"
事件对象,在标签使用事件时传入$event
e.target
可以获得对应的dom对象e.target.value
可以获得input标签的值内容双向数据绑定ngModel:只针对表单元素【MVVM模型,模型变了页面就变,页面变了数据就变】
使用[]
绑定数据时,如果想在ts数据前后添加内容使用字符串拼接的方式
<input type="checkbox" [id]="'check'+key"/>
使用service服务
ng g service serviceName
Angular中的Dom操作使用@ViewChild
注意:ngOnInit()方法是组件和指令初始化完成的周期钩子,不是真正Dom加载完成。ngAfterViewInit()方法是视图加载以后触发的方法,此时Dom已加载完成。
基本使用
定义标签
<div #test>div>
获取Dom节点
@ViewChild('test')
test:ElementRef;
//获取Dom节点的方法
ngAfterViewInit() {
//通过nativeElement获取Dom节点
this.test.nativeElement;
}
父子组件通过ViewChild调用子组件的方法**【用于获取子组件实例 】**
在父组件中给子组件定义一个名称
<app-header #headerChild>app-header>
引入@ViewChild
import {ViewChild} from '@angular/core';
将ViewChild和刚才的组件关联
@ViewChild('headerChild')
header:any;
调用子组件
run() {
this.header.testMethod();//testMethod方法是HeaderChild组件中的方法
}
父组件与子组件之间的通讯
父组件给子组件传值@Input
父组件调用子组件的时候传值在属性中
子组件通过@Input接受父组件传递的数据
export class HeaderComponent implements OnInit {
@Input()
msg:string;
}
子组件通过@Output触发父组件的方法
子组件中实例化EventEmitter可以向父组件传递数据
@Output()
private outer = new EventEmitter();
子组件使用EventEmitter对象的emit方法可以传递实时广播
sendParent() {
this.outer.emit('msg from child');
}
父组件调用子组件的时候接收事件,outer就是子组件的EventEmitter对象
<app-header (outer)="runParent($event)">app-header>
父组件接收数据会调用runParent方法,此时可以拿到子组件数据
runParent(msg:string) {
alert(msg);
}
非父子组件通讯
Angular中的生命周期函数
定义需要执行回调函数的方法
getCallbackData(cd) {//cd是回调函数
setTimeout(()=>{
var username = 'Jack';
cd(username);//等待异步方法执行时调用回调函数
},1000)
}
调用方法时传入回调函数
this.getCallbackData((username:string)=>{
console.log(username);//传入的回调函数执行打印的功能
})
此时执行到调用时会打印Jack
定义需要执行回调函数的方法
getPromiseData() {
return new Promise((resolve,reject)=>{
//resolve表示成功后执行的回调函数,reject表示失败后执行的回调函数
setTimeout(()=>{
var username = 'Jack';
resolve(username);
},1000);//设置异步方法
})
}
调用方法时传入回调函数,使用promise获取异步数据
var promiseObject = this.getPromiseData();//获取到方法返回的Promise对象
promiseObject.then((data)=>{//使用Promise对象的then方法设置resolve函数内容
console.log(data)
})
RxJs处理异步主要是通过其中的Observable对象完成的,且RxJs和Promise的基本用法类似,只是关键字不同。Promise里面用的是then()和resolve(),而RxJs里面用的是next()和subscribe()。
定义需要执行回调函数的方法
import {Observable} from 'rxjs';
//...
getRxjsData() {
return new Observable((observable)=>{
setTimeout(()=>{
var username = 'Jack';
//成功时调用next()方法执行
observable.next(username);
//失败时调用error()方法执行
//observable.error('这是一个错误信息');
},1000);//设置异步方法
})
}
调用方法时传入成功和失败执行的方法
var rxjsData = this.getRxjsData();//返回的是Observable对象
rxjsData.subscribe((data)=>{
console.log(data);//第一个参数定义回调成功next的调用方法
});
Promise创建之后,动作是无法撤回的,Observable不同,动作可以通过unsubscribe()方法中途撤回,而且Observable在内部做了智能的处理。
var stream = this.getRxjsData();
var subscribedStream=streem.subscribe((data)=>{
console.log(data);
});
//使用订阅返回的内容进行撤回操作,取消订阅
setTimeout(()=>{
subscribedStream.unsubscribe();
},1000);
Promise无法做到让异步里面的方法多次执行,最终结果要么resole(兑现)、要么 reject (拒绝),而且都只能触发一次。如果在同一个 Promise 对象上多次调用 resolve 方法, 则会抛异常。而Observable 不一样,它可以不断地触发下一个值。
Promise对象如果按照如下的方式使用setInterval()多次执行resolve方法会抛出异常
let promise = new Promise(resolve => { setInterval(() => {
resolve('---promise setInterval---'); }, 2000);
});
promise.then(value => console.log(value));
RxJs对象如果按照如下的方式使用setInterval()多次执行next()方法会正常执行
let stream = new Observable(observer => { let count = 0;
setInterval(() => {
observer.next(count++);
}, 1000);
});
stream.subscribe(value => console.log("Observable>"+value));
RxJs使用的工具函数
注意:Angular6 以后使用以前的 rxjs 方法,必须安装 rxjs-compat 模块才可以使用 map、filter 方法。
npm install rxjs-compat
filter方法主要作用是过滤;map方法主要作用是对数据处理,将处理之后的数据返回。
Angular6之前使用方法
import {Observable} from 'rxjs';
import 'rxjs/Rx';
//...
let stream= new Observable(observer => {
let count = 0;
setInterval(() => {
observer.next(count++); }, 1000);
});
stream.filter(val=>val%2==0)
.subscribe(value => console.log("filter>"+value));
stream.map(value => {return value * value})
.subscribe(value => console.log("map>"+value));
Angular6.X以后Rxjs6.x的变化及使用
RxJs变化参考文档http://bbs.itying.com/topic/5bfce189b110d80f905ae545
RXJS6 改变了包的结构,主要变化在 import 方式和 operator 上面以及使用 pipe()
import {Observable} from 'rxjs';
import {map,filter} from 'rxjs/operators';
//...
let stream= new Observable(observer => {
let count = 0;
setInterval(() => {
observer.next(count++);
}, 1000);
});
stream.pipe(filter(val=>val%2==0))//表示只保留偶数
.subscribe(value => console.log("filter>"+value));
//可以使用pipe()方法,定义filter和map等方法的处理
stream.pipe(filter(val=>val%2==0), map(value => {return value * value }))
.subscribe(value => console.log("map>"+value));
RxJs延迟执行
在RxJs中可以使用fromEvent(dom,时间).pipe(()=>{处理函数})
的方式将Dom转换成dom流,对dom流进行处理,实例如下
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`));
Angular5.x 以后 get、post 和和服务器交互使用的是HttpClientModule 模块。
app.module.ts中引入HttpClientModule并注入(imports)
在使用的地方使用HttpClient在构造函数中依赖注入
constructor(public http:HttpClient){}
使用get方法请求数据
this.http.get('http://test.com').subscribe(response=>{
console.log(response);
});
同样引入HttpClientModule和依赖注入HttpClient对象
定义请求头内容并发送post请求
const httpOptions = {//定义请求头对象内容
headers: new HttpHeaders({'Content-Type':'application/json'})
}
var api = 'http://test.com';
this.http.post(api,{'username':'Jack'},httpOptions).subscribe(reponse=>{
console.log(response);
})
当后台不允许跨域时,可以发送jsonp解决跨域问题(跨域解决方案),jsonp的原理是本地写一个方法在远程进行执行并返回给本地【使用jsonp发送请求要求服务器必须支持jsonp】
在app.module.ts中引入HttpClientModule/HttpClientJsonpModule并注入
使用的ts中构造方法注入HttpClient
发送jsonp请求数据
let api = 'http://test.com';
//jsonp方法的第二个参数是callback或者cd(根据服务器而定的)
this.http.jsonp(api,'callback').subscribe(response=>{
console.log(response);
})
安装axios
cnpm install axios --save
用到的地方引入axios
import axios from 'axios';
使用axios
axiosGet(api) {
return new Promise((resolve,reject)=>{
axios.get(api)
.then((response)=>{
//handle success
resolve(response);
});
})
}
let promiseObj = this.axiosGet(api);
promiseObj.then((val)=>{
console.log(val)
})
基本路由知识请查阅其他材料,本章介绍路由中易混淆内容
html编写routerLink进行点击跳转路由
<a routerLink="/home">首页a>
<a [routerLink]="['/home']">首页a>
<a routerLink="/news">新闻a>
ts设定默认路由
{
//匹配不到路由的时候默认加载的组件或者跳转的路由
path: '**',
/*任意的路由*/
// component:HomeComponent redirectTo:'home'
}
使用routerLinkActive可以设置当当前路由被选中时,则显示active样式(active样式需要自己编写.active{color:red;}
)
<h1>
<a [routerLink]="[ '/home' ]" routerLinkActive="active">首页a>
<a [routerLink]="[ '/news' ]" routerLinkActive="active">新闻a>
h1>
路径方式传值是在ActivatedRoute对象的params属性中保存,请求参数方式传值是在ActivatedRoute对象的queryParams属性中保存,且都是Observable对象
配置动态路由
const routes: Routes = [
{path: 'home', component: HomeComponent},
{path: 'news', component: NewsComponent},
{path: 'newscontent/:id', component: NewscontentComponent},
{
path: '',
redirectTo: '/home',//使用redirectTo定义当匹配当前路由时重定向到哪个路由
pathMatch: 'full'
}];
跳转传值
<a [routerLink]="['/newscontent/',aid]">跳转到详情a>
<a routerLink="/newscontent/{{aid}}">跳转到详情a>
获取动态路由的值
import { ActivatedRoute} from '@angular/router';
constructor( private route: ActivatedRoute) {}
ngOnInit() {
console.log(this.route.params);
this.route.params.subscribe(data=>this.id=data.id);
}
请求参数形式传值
<a [routerLink]="['/newscontent']" [queryParams]="{aid:key}">跳转a>
获取参数形式传值的数据
import { ActivatedRoute} from '@angular/router';
constructor( private route: ActivatedRoute) {}
ngOnInit() {
console.log(this.route.queryParams);
this.route.queryParams.subscribe(data=>this.id=data.aid);
}
动态路由的ts跳转
引入Router
import { Router } from '@angular/router';
初始化Router对象
constructor(private router: Router) {}
路由跳转
this.router.navigate(['/news', hero.id]);
路由Get传值(请求参数传值)ts跳转
引入NavigationExtras
import { Router ,NavigationExtras} from '@angular/router';
定义一个 goNewsContent 方法执行跳转,用 NavigationExtras 配置传参
goNewsContent(){
let navigationExtras: NavigationExtras = {
queryParams: { 'session_id': '123' }//配置queryParams
};
this.router.navigate(['/news'],navigationExtras);
}
父子路由实战
配置路由
{
path: 'news',
component:NewsComponent,
children: [
{
path:'newslist',
component:NewslistComponent
},
{
path:'newsadd',
component:NewsaddComponent
}
]
}
父组件中定义router-outlet
<router-outlet>router-outlet>
cli
生成module:ng g m testmodule
,创建带路由的module:ng g m testmodule --routing
通过配置懒加载路由的方式实现模块的懒加载
使用loadChildren声明懒加载路由模块,#
前是module模块路径,#
后是module名
实例代码
const routes: Route = [
{
path:'user',
loadChildren:'./module/user/user.module#UserModule'
}
]