命令行汇总
1
2
3
4
5
6
7
npm install -g @angular/cli
ng version
ng new projectName // create new angular project
ng serve --open // run project
ng g component <component-name> // create new component
ng g service <service-name> // create new service
使用指定版本的Angular
1
2
3
npm uninstall -g @angular/cli
npm install -g @angular/cli@13.2.0
ng new my-app-name
将第三方module升到最新
1
2
3
npm install -g npm-check-updates
ncu --upgrade
npm install
基本概念
组件
组件是构成应用的砖块。组件包括三个部分:
1
2
3
带有 @Component() 装饰器的 TypeScript 类
HTML 模板
样式文件
@Component() 装饰器会指定如下 Angular 专属信息:
1
2
3
一个 CSS 选择器,用于定义如何在模板中使用组件。
一个 HTML 模板,用于指示 Angular 如何渲染此组件。
一组可选的 CSS 样式,用于定义模板中 HTML 元素的外观。
每个组件都必须声明在(且只能声明在)一个 NgModule
中。
模板
每个组件都有一个 HTML 模板,用于声明该组件的渲染方式。你可以内联它或用文件路径定义此模板。
Angular 使用额外的语法扩展了 HTML,使你可以从组件中插入动态值。当组件的状态更改时,Angular 会自动更新已渲染的 DOM。
1
<p> { { message } }</p>
双花括号 —— 它们指示 Angular 对其中的内容进行插值。
1
<p [id]="sayHelloId" [style.color]="fontColor">You can set my color in the component!</p>
方括号 —— 属性绑定,在将 Property 或 Attribute 绑定到组件类中的值。
1
<button (click)="sayMessage()" [disabled]="canClick">Trigger alert message</button>
圆括号 —— 事件监听
安装
- Install NodeJs
-
Start a cmd and install following command:
1
npm install -g @angular/cli
-
Input following command to check Angular version
1
ng version
-
VSCode 安装插件
1
Angular Snippet
基础
创建一个项目
Initialize a new project:
1
ng new projectName
可以使用ng new projectName --skip-install
跳过依赖安装,然后使用npm install
安装依赖项
运行应用
1
ng serve --open
目录结构
angular.json | 里面记录了网页的入口 index, main |
package.json | 里面记录了所有的script命令 |
src/index.html | 网站首页 |
src/main.ts | 加载哪个module |
src/app/app.module.ts | app module里面加载了哪个component |
src/app/app.component.ts | Angular根组件,里面包括 修饰器, template,style和Appcomponent的一些属性设定。 |
根模块app.module.ts:
安装其他module
1
2
npm install jquery@3.1.1 --save
npm install bootstrap@3.3.7 --save
安装完成之后,package.json会发生变化,记录已经安装的module。
在angular.json中新安装的module:
1
2
3
4
"scripts": [
"../node_modules/jquery/dist/jquery.js",
"../node_modules/bootstrap/dist/js/bootstrap.js"
]
安装module对应的types:
1
2
3
npm install @types/jquery@2.0.39 --save-dev
npm install @types/bootstrap@3.3.32 --save-dev
创建新组件
1
ng g component News
每添加一个组件,会生成对应的文件夹和文件,并且自动在app.modules.ts里面注册该组件:
1
2
3
4
5
6
7
import { NewsComponent } from './News/news.component';
@NgModule({
declarations: [
AppComponent,
NewsComponent
],
每个组件包括三部分html, css, ts
:
ts文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-news', // component名字
templateUrl: './news.component.html', // html
styleUrls: ['./news.component.css'] // css样式
})
export class NewsComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}
创建新的service
1
ng g service services/storage
一个新创建好的空服务
1
2
3
4
5
6
7
8
9
10
11
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class StorageService {
constructor() { }
// Add new function here
}
需要在app.modules.ts
里面引入新添加的服务
1
2
3
import {StorageService} from './services/storage.service';
...
providers: [StorageService],
在component中调用该service:
1
2
3
4
5
import {StorageService} from './services/storage.service';
constructor(public storage:StorageService) {
this.storage.function();
}
基本数据结构
-
数组
1 2 3 4 5 6 7 8 9
public arr:any[]=['111','222','333']; public userlist:any[]=[{ username:'Zhang', age:20 },{ username:'Li', agent:21 }]
绑定
-
绑定数据
component.ts:
1
title:string ='data'; //声明一个属性
compoonent.html:
1
<h1> { {title} } </h1>
双花括号语法是 Angular 的插值绑定语法。 这个插值绑定的意思是把组件的 title 属性的值绑定到 HTML 中的 h1 标记中。
-
绑定属性
component.html:
1
<div [title]="student"></div>
component.ts
1
student:string='abc';
-
绑定HTML:
component.html:
1
<span [innerHTML]="content"></span>
component.ts:
1
content="<h2>这是一个html标签</h2>"
-
绑定数组
component.html:
1 2 3
<li *ngFor="let item of list"> { {item} } </li>
component.ts:
1
list:string[] = ['111','222','333']
-
绑定事件:
html:1
<button (click)="fun()">执行事件</button>
ts:
1 2 3
fun(){ console.log("test"); }
input事件绑定:
1
<input type="text" (keydown)="keyDown($event)"/>
ts:
1 2 3
keyDown(event){ console.log(event.target.value); }
-
双向数据绑定 MVVM 只是针对表单
双向数据绑定必须引入
FormModule
在app.module.ts
中:1 2 3 4 5
import {FormsModule} from '@angular/forms' import:[ FormsModule, ],
html:
1
<input type="text" [(ngModel)]="keywords"/>
ts:
1
keywords:string="default value"
数据用双括号{ { } }
,属性用[]
绑定,事件用()
绑定,双向绑定用[()]
指令语句
-
ngFor
1 2 3 4 5 6 7
<li *ngFor="let item of list"> { {item} } </li> <li *ngFor="let item of list;let key=index;"> { {key} }----{ {item} } </li>
-
ngIf
1 2 3
<div *ngIf="flag"> </div>
-
ngSwitch
1 2 3 4 5 6 7 8
public orderStatus:number=1 <ul [ngSwitch]="orderStatus"> <li *ngSwitchCase="1">已支付</li> <li *ngSwitchCase="2">订单已经确认</li> <li *ngSwitchCase="3">已发货</li> <li *ngSwitchDefault>无效</li> </ul>
-
ngClass
1
<div [ngClass]="{'red': flag}">ngClass演示</div>
第一条显示红色:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
css: .red { color:red; } .orange{ color:orange; } html: <ul> <li *ngFor="let item of list; let key=index;" [ngClass]="{'red': key==0, 'orange':key==1}"> { {key} } -- { {item} } </li> </ul>
-
ngStyle
1
<p [ngStyle]="{'color': 'red'}">ngStyle</p>
管道
管道用来格式化数据, 处理原始值到显示值的转换
1
2
3
4
5
public birthday:any=new Date();
<p>我的生日是{ {birthday | date:'yyyy-MM-dd HH:mm:ss'} }</p>
<p>圆周率是{ {pi | number:'2.2-2'} }</p>
自定义管道
1
ng g pipe pipe/multiple
遇到以下问题:
1
No provider for ControlContainer ("[ERROR ->]<form name="searchForms" role="forms">
解决方法:
在使用管道的时候,需要引入 ReactiveFormsModule,同时还要引入 FormsModule
1
2
3
4
5
6
imports: [
BrowserModule,
AppRoutingModule,
ReactiveFormsModule,
FormsModule,
],
表单
采用双向绑定的方式:
html:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<div class="people_list">
<ul>
<li>姓名: <input type="text" [(ngModel)]="peopleInfo.username" class="username"></li>
<li>性别:
<input type="radio" value="1" name="sex" id="sex1" [(ngModel)]="peopleInfo.sex">
<label for="sex1">男</label>
<input type="radio" value="2" name="sex" id="sex2" [(ngModel)]="peopleInfo.sex">
<label for="sex2">女</label>
</li>
<li>城市:
<select name="city" id="city" [(ngModel)]="peopleInfo.city">
<option [value]="item" *ngFor="let item of cityList"></option>
</select>
</li>
<li>爱好:
<span *ngFor="let item of peopleInfo.hobbyList; let key=index;">
<input type="checkbox" [id]="'check'+key" [(ngModel)]="item.checked" >
<label [for]="'check'+key"></label>
</span>
</li>
<li>备注:
<textarea name="mark" id="mark" cols="30" rows="10" [(ngModel)]="peopleInfo.mark"></textarea>
</li>
</ul>
<button (click)="doSubmit()" class="submit">获取表单的内容</button>
</div>
css:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
*{
margin:0px;
padding:0px;
}
ul,ol{
list-style-type:none;
}
h2{
text-align:center;
}
.people_list{
width: 400px;
margin:40px auto;
padding: 20px;
border: 1px sold #eee;
li{
height:50px;
line-height:50px;
input{
width:300px;
height:32px;
}
}
}
ts:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
export class FormComponent implements OnInit {
cityList:string[] = ['北京','上海','深圳'];
public peopleInfo:any={
username:'',
sex:'1',
city:'北京',
hobbyList: [{
title:'吃饭',
checked:false
},{
title:'睡觉',
checked:false
},{
title:'玩游戏',
checked:true
}],
mark:''
}
constructor() { }
ngOnInit(): void {
}
doSubmit(): void{
console.log(this.peopleInfo);
}
}
LocalStorage
HTML5 提供了两种在客户端存储数据的新方法:
localStorage - 没有时间限制的数据存储
sessionStorage - 针对一个 session 的数据存储
localStorage生命周期是永久,这意味着除非用户显示在浏览器提供的UI上清除localStorage信息,否则这些信息将永远存在。存放数据大小为一般为5MB,而且它仅在客户端(即浏览器)中保存,不参与和服务器的通信。
1
2
3
4
5
6
7
8
9
10
11
set(key,value){
localStorage.setItem(key, JSON.stringify(value));
}
get(key){
return JSON.parse(localStorage.getItem(key));
}
remove(key){
localStorage.removeItem(key);
}
查看方法
进入开发者工具
选择 Application
在左侧 Storage 下 查看 Local Storage 和 Session Storage
操纵DOM元素
-
原生js操作
html:1 2 3
<div id="box1"> 我是一个dom节点 </div>
ts:
建议把dom操作放在视图加载完成`ngAfterViewInit`以后触发1 2 3 4 5
ngAfterViewInit():void{ let obox:any=document.getElementById('box1'); console.log(obox.innerHTML); obox.style.color="blue" }
-
ViewChild
ViewChild对原生DOM进行了封装.
html:1 2 3
<div #myBox> 我是一个dom节点 </div>
ts:
1 2 3 4 5 6 7 8 9
// 引入ViewChild import {component,onInit, ViewChild} from '@angular/core'; @ViewChild('myBox') myBox:any; ngAfterViewInit():void{ this.myBox.nativeElement.style.width='100px'; this.myBox.nativeElement.style.height='100px'; }
ViewChild允许在父组件中调用子组件的方法
news.component.html:1
<app-header #header></app-header>
news.component.ts:
1 2 3 4 5
@ViewChild('header') header:any; ngAfterViewInit():void{ this.header.childFun(); }
组件之间通讯
父 -> 子 @Input装饰器
父组件不仅可以给子组件传递简单的数据, 还可以把自己的方法以及整个父组件传递给子组件。
父组件:
ts:
1
2
3
4
5
6
public title:string="首页组件的标题";
run()
{
console.log("这是父组件的方法");
}
html:
1
<app-header [title]="title" [run]='run'></app-header>
子组件app-header:
ts:
1
2
3
4
5
6
7
8
9
import {Input} from '@angular/core'
@Input() title:any; //接受父组件传来的数据
@Input() run:any;
getParentRun()
{
run(); //执行父组件的run方法
}
html:
1
2
3
<header></header>
<button (click)="getParentRun()">子组件执行父组件的方法</button>
子 -> 父
方法1:使用ViewChild获取DOM
子组件:
ts:
1
2
3
4
public msg="我是子组件的一个msg";
run(){
alert("我是子组件的run方法");
}
父组件:
html:
1
2
3
4
<app-footer #footer></app-footer>
<button (click)="getChildMsg()>获取字组件数据</button>
<button (click)="getChildRun()">执行子组件的方法</button>
ts:
1
2
3
4
5
6
7
8
9
10
import {ViewChild} from '@angular/core';
@ViewChild('footer') footer:any;
getChildMsg(){
alert(this.footer.msg)
}
getChildRun(){
this.footer.run()
}
方法2: @Output + 事件驱动 EventEmitter
子组件:
ts:
1
2
3
4
5
6
7
import {Output,EventEmitter} from '@angular/core';
@Output() private outer=new EventEmitter<string>();
sendParent(){
this.outer.emit("msg from child");
}
html:
1
<button (click)=sentParent()>通过子组件向父组件广播</button>
父组件:
html:
1
<app-header (outer)="run($event)"></app-header>
ts:
1
2
3
4
run(e)
{
console.log(e);
}
非父子附件之间通信
- 通过服务来实现非父子组件之间的通信
- 通过LocalStorage
Angular生命周期钩子
生命周期函数通俗的讲就是组件创建、组件更新、组件销毁的时候会触发的一系列的方法。
Angular 会按以下顺序执行钩子方法。你可以用它来执行以下类型的操作。
钩子方法 | 用途 | 时机 |
---|---|---|
ngOnChanges() | 当 Angular 设置或重新设置数据绑定的输入属性时响应。 该方法接受当前和上一属性值的 SimpleChanges 对象. 注意,这发生的非常频繁,所以你在这里执行的任何操作都会显著影响性能。 | 在 ngOnInit() 之前以及所绑定的一个或多个输入属性的值发生变化时都会调用。 |
ngOnInit() | 在 Angular 第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。 | 在第一轮 ngOnChanges() 完成之后调用,只调用一次。 |
ngDoCheck() | 检测,并在发生 Angular 无法或不愿意自己检测的变化时作出反应。 | 紧跟在每次执行变更检测时的 ngOnChanges() 和 首次执行变更检测时的 ngOnInit() 后调用。 |
ngAfterContentInit() | 当 Angular 把外部内容投影进组件视图或指令所在的视图之后调用。 | 第一次 ngDoCheck() 之后调用,只调用一次。 |
ngAfterContentChecked() | 每当 Angular 检查完被投影到组件或指令中的内容之后调用。 | ngAfterContentInit() 和每次 ngDoCheck() 之后调用 |
ngAfterViewInit() | 当 Angular 初始化完组件视图及其子视图或包含该指令的视图之后调用。 | 第一次 ngAfterContentChecked() 之后调用,只调用一次。 |
ngAfterViewChecked() | 每当 Angular 做完组件视图和子视图或包含该指令的视图的变更检测之后调用。 | ngAfterViewInit() 和每次 ngAfterContentChecked() 之后调用。 |
ngOnDestroy() | 每当 Angular 每次销毁指令/组件之前调用并清扫。 在这儿反订阅可观察对象和分离事件处理器,以防内存泄漏。 | 在 Angular 销毁指令或组件之前立即调用。 |
获取异步数据
回调函数
request.service.ts:
1
2
3
4
5
6
getCallbackData(cb){
setTimeout(()=>{
var data='张三';
cb(data);
},1000)
}
HomeComponent.ts:
1
2
3
4
5
6
7
8
9
import {RequestService} from '../../services/request.servcie'
constructor(public request:RequestService){}
ngOnInit(){
let callback = this.request.getCallbackData((data)=>{
console.log(data);
});
}
Promise
request.service.ts:
1
2
3
4
5
6
7
8
getPromiseData(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
var data='张三';
resolve(data);
},1000)
})
}
HomeComponent.ts:
1
2
3
4
5
6
7
8
9
10
import {RequestService} from '../../services/request.servcie'
constructor(public request:RequestService){}
ngOnInit(){
var prmiseData=this.request.getPromiseData();
promiseData.then((data)=>{
console.log(data);
})
}
Rxjs
request.service.ts:
1
2
3
4
5
6
7
8
9
10
11
import{Observable} from 'rxjs'
getRxjsData(){
return new Observable((observer)=>{
setTimeout(()=>{
var data='张三';
observer.next(data);
//observer.error("error message");
},1000)
})
}
HomeComponent.ts:
1
2
3
4
5
6
7
8
9
10
import {RequestService} from '../../services/request.servcie'
constructor(public request:RequestService){}
ngOnInit(){
var rxjsData = this.request.getRxjsData();
rxjsData.subscribe((data)=>{
console.log(data);
})
}
相比Promise方法, Rxjs可以取消订阅操作unsubscribe
, 多次执行, 有map
, filter
工具,可以对数据进行处理.
filter
筛选数据,map
处理数据:
request.service.ts:
1
2
3
4
5
6
7
8
9
10
11
import{Observable} from 'rxjs'
getRxjsIntervalNum(){
let count=0;
return new Observable((observer)=>{
setInterval(()=>{
count++;
observer.next(count)
},1000)
})
}
HomeComponent.ts:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import {RequestService} from '../../services/request.servcie'
import {map, filter} from 'rxjs/operators'
var streamNum=this.request.getRxjsIntervalNum();
streamNum.pipe(
filter((value)=>{
if(value%2==0){
return true; //筛选偶数
}
})
map((value)=>{
return value * value; //处理数据
})
)
.subscribe((data)=>{
console.log(data);
})
streamNum.pipe(
)
数据交互 get post
get
需要在app.module.ts中引入httpClientModule
1
2
3
4
5
import {HttpClientModule} from '@angular/common/http';
imports:[
HttpClientModule
]
在需要使用的地方:
1
2
3
4
5
6
7
8
9
10
import {HttpClientModule} from '@angular/common/http';
constructor(public http:HttpClient){}
get(){
var api="test.com/api/productlist";
this.http.get(api).subscribe(response:any => {
console.log(response);
});
}
get请求底层封装了Rxjs
post
1
2
3
4
5
6
7
8
const httpOptions={
headers:new httpHeaders({'Content-Type':'application/json'})
}
var api="test.com/api/doLogin";
this.http.post(api,{username:'张三',age:'20'}, httpOptions).subscribe(response =>{
console.log(response);
});
Jsonp
Jsonp是跨域的一种解决方案, 前提是服务器支持jsonp请求
需要在app.module.ts中引入httpClientModule
1
2
3
4
5
6
import {HttpClientModule,HttpClientJsonpModule} from '@angular/common/http';
imports:[
HttpClientModule,
HttpClientJsonpModule
]
在需要使用的地方:
1
2
3
4
5
6
7
8
9
10
import {HttpClientModule} from '@angular/common/http';
constructor(public http:HttpClient){}
getJsonpData(){
let api="test.com/api/productlist";
this.http.jsonp(api, 'callback').subscribe((response)=>{
console.log(response);
})
}
使用第三方模块axios请求数据
1
npm install axios --save
路由
路由就是根据不同的url地址,动态的让根组件加载其他组件来实现一个单页面应用。
在src\app\app-routing.module.ts
中引入并配置路由
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import {HomeComponent} from './home/home.component';
...
const routes:Routes =[
{path: 'home', component:HomeComponent},
{path: 'news', component:NewsComponent},
{path: 'newscontent/:id', component:NewscontentComponent},
{
path:'',
redirectTo:'/home',
pathMath: 'full'
}
]
在html中<router-outlet>
用于动态加载组件
1
2
3
4
5
<h1>
<a routerLink="/home">首页</a>
<a routerLink="/news">新闻</a>
</h1>
<router-outlet></router-outlet>
默认路由:
1
2
3
4
5
6
const routes:Routes =[
...
{
path:'**', redirectTo:'home'
}
]
当前选中页面高亮:
HTML:
1
2
3
4
5
<h1>
<a routerLink="/home" routerLinkActive="active">首页</a>
<a routerLink="/news" routerLinkActive="active">新闻</a>
</h1>
<router-outlet></router-outlet>
css:
1
2
3
.active{
color:red;
}
路由传值
get传值
使用queryParams进行传值
html:
1
2
3
4
5
<ul>
<li *ngFor="let item of list; let key=index;">
<a [routerLink]="['/newscontent']" [queryParams]="{aid:key,name:'张三'}">跳转到新闻详情</a>
</li>
</ul>
在子组件ts中接收参数:
1
2
3
4
5
6
7
8
9
import {ActiveRoute} from '@angular/router';
constructor(public route:ActiveRoute){}
ngOnInit(){
this.route.queryParams.subscribe((data)=>{
console.log(data);
})
}
动态路由
修改路由配置
1
2
3
const routes:Routes =[
{path: 'newscontent/:aid', component:NewscontentComponent},
]
html:
1
2
3
4
5
<ul>
<li *ngFor="let item of list;let key=index>
<a [routerLink]="['/newscontent', key]">跳转到新闻详情</a>
</li>
</ul>
在子组件ts中接收参数:
1
2
3
4
5
6
7
8
9
import {ActiveRoute} from '@angular/router';
constructor(public route:ActiveRoute){}
ngOnInit(){
this.route.params.subscribe((data)=>{
console.log(data);
})
}
动态路由js跳转
html:
1
<button (click)="goNewsContent()">js跳转路由</button>
ts:
1
2
3
4
5
6
7
8
9
10
11
import {Router} from '@angular/router'
constructor(public route:Router){}
goNewsContent(){
this.router.navigate(['/newscontent','1234']);
}
goHome(){
this.router.navigate(['/home']);
}
js跳转路由并且get传值
需要引入NavigationExtras模块
1
2
3
4
5
6
7
8
9
10
import {Router,NavigatioinExtras} from '@angular/router';
goNewConent(){
let navigationExtras:NavigationExtras ={
queryParams:{'session_id':'123'},
fragment:'anchor'
}
this.router.navigate(['/news'], navigationExtras);
}
嵌套路由
使用children
修改路由配置
1
2
3
4
5
6
7
8
9
10
const routes:Routes =[
{
path: 'home', component:HomeComponent,
children:[
{path:'welcome', component:WelcomeComponent},
{path:'setting', component:SettingComponent},
{path: '**', redirectTo:'welcome'},
]
},
]
html:
1
2
3
<a [routerLink]="['/home/welcome']">欢迎首页</a>
<router-outlet></router-outlet>
辅助路由
1
2
3
4
5
<a [routerLink]="[{outlets:{aux:'chat'}}]">开始聊天</a>
<a [routerLink]="[{outlets:{aux:null}}]">结束聊天</a>
<router-outlet name="aux"></router-outlet>
{path:'chat', component:ChatComponent, outlet: 'aux'}
路由守卫
-
CanActivate:处理导航到某路由的情况。
1 2 3 4 5
export class LoginGuard implements CanActivate{ CanActivate(){ return true; } }
配置路由:
1 2 3 4 5 6 7
const routes:Routes =[ {path:'product/:id', component:ProductComponent, canActivate:[LoginGuard]}, ] @NgModule({ providers: [LoginGuard] })
-
CanDeactivate:处理从当前路由离开的情况.
1 2 3 4 5
export class UnsavedGuard implement CanDeactivate<ProductComponent>{ canDeactivate(component:ProductComponent){ return window.confirm("你还没有保存,确定要离开吗?"); } }
配置路由:
1 2 3 4 5 6 7
const routes:Routes =[ {path:'product/:id', component:ProductComponent, canDeactivate:[UnsavedGuard]}, ] @NgModule({ providers: [UnsavedGuard] })
-
Resolve:在路由激活之前获取路由数据
自定义模块
1
ng g module module/user
在自定义模块中创建新的component
1
ng g component module/user/components/order
在自定义模块的module.ts
中指定要export的组件
user.module.ts
1
exports:[UserComponent],
引入自定义模块:
1
2
3
4
5
import {UserModule} from './module/user/user.module';
imports:[
UserModule,
],
自定义模块的懒加载
创建模块时自动创建路由
1
ng g module module/user --routing
创建模块的根组件
1
ng g component module/user
配置自定义模块的路由
user-routing.module.ts
1
2
3
4
5
const routes:Routes =[
{
path:'', component:UserComponent
}
]
修改根路由配置
app-routing.module.ts
1
2
3
4
5
const routes:Routes=[
{
path:'user', loadChildren:'./module/user/user.module#UserModule'
}
]
响应式编程
Other
定时器
1
2
3
4
5
6
7
8
9
// 只执行一次
setTimeout(()=>{
console.log("write log after 1 second");
},1000)
// 执行多次
SetInterval(()=>{
console.log("write log every 1 second");
}, 1000)
reference
localStorage、sessionStorage、Cookie的区别及用法
问题
- .debounceTime
需要 import ‘rxjs/Rx’ //搜索
npm install –save rxjs-compat