一:開發環境準備
下載安裝angular
Node.js,webpack,腳手架搭建
查看node版本:node –v
Angular8只支持node10以上版本
查看npm版本:npm –v
刪除已安裝的舊版本的angular:cnpm uninstall –g @angular/cli
刪除angular安裝包
清除緩存:npm cache clean --force
全局安裝angular最新版本:cnpm install –g @angular/cli@latest
查看是否安裝成功:ng version
gnvm管理node
下載gnvm.exe放在安裝node的路徑下,雙擊gnvm.exe運行
以管理員身份運行:gnvm version
- 使用gnvm下載node:gnvm install 6.13
- 下載最新版本的node:gnvm update latest
- 查看安裝了那些node版本:gnvm ls
- 使用某個版本:gnvm use 6.11.3
創建項目:ng new demo
報錯:npm ERR code ERR_STREAM_WRITE_AFTER_END
解決方法:降低npm版本:npm i –g [email protected](會有不支持node10.16.3的警告)
再重新創建:ng new demo(cmd下)
切換到目錄:cd demo
運行項目:ng serve –open(angular6需node10以上)
二:基礎
組件/指令
模塊/路由
依賴注入
rxjs/Http
組件及組件樹:
1.創建組件
在component目錄下創建header組件:ng g component comments/header
2.組件內容
組件內包含:html和css和ts
3.ts文件構成
class組件類和裝飾器@Component構成
裝飾器:賦予類更豐富的元數據,裏面可以定義組件的模板template
@Component({
selector:’hello’, //匹配hello標籤
template:’<p>{{greeting}}</p>’//這個模板會被插入到hello標籤裏
})
export class HelloComponent{
private greeting:string; //屬性聲明
constructor(){
this.greeting=’Hello Angular 2’} //屬性賦值
}
4.屬性和對象的聲明和使用(ts裏)
數據類型 | 聲明 | 使用 |
屬性 | public name:any=’張三’ | <div [title]=”name”> |
public name:string; | ||
constructor(){ this.name=’張三’ } |
||
對象 |
public userinfo:object={ name:’張三’, age:’20’ } |
{{userinfo.name}} |
5.數據的使用(html裏)
插值:{{greeting}}
數據綁定:屬性綁定,事件綁定,雙向綁定
綁定的類型 | 包含內容 | 例子 |
Html綁定 |
public contant=’<div>123</div>’ <div [innerHTML]=’contant’> |
|
Class綁定 |
<div [ngClass]=”{ ‘box1’:ture }”> <li *ngFor=”let item of data1;let key=index” [ngClass]=”{red:key==0}”></li> |
|
Style綁定 |
<li [ngStyle]=”{‘color’:licolor}”></li> private licolor:ang=”red”; |
|
屬性綁定 | value |
<input [value]=”myData”/> |
src |
pubilc picUrl:string=”../../../assets/a.JPG”; <img [src]=”picUrl”> |
|
事件綁定 |
鍵盤事件 keydown |
keyDown(e){ console.log(e); console.log(e.key); console.log(e.keyCode); } <input type=”text” (keydown)=”kayDown($event)”> |
鍵盤事件 keyup |
keyUp(e){console.log(e.target.value)} <input type=”text” (keyup)=”kayUp($event)”> |
|
鼠標點擊事件 click |
//點擊後獲取數據 public title:any=”原始標題”; getData(){alert(this.title)} <button (click)=”getData”>點擊</button> |
|
//點擊後設置數據 public title:any=”原始標題”; setData(){this.title=”標題被改變”} <button (click)=”setData”>點擊</button> |
||
//點擊後獲取對象 getDom(e){var dom=e.target;dom.style.color=”red”} <button (click)=”getDom($event)” >點擊</button> |
||
雙向綁定 | <input [(ngModel)]=”myData”/> |
雙向綁定
1.導入模塊
import {FormsModule} from ‘@angular/forms’
2.模塊註冊
@NgModule({
imports:[FormsModule]
})
3.使用:
public keywords:any;
<input type=”text” [(ngModle)]=”keywords”>
{{keywords}}
指令和命令
包括屬性指令和結構指令,組件也是指令的一種
屬性指令:改變組件外觀或行爲,如樣式
結構指令:改變模板的Dom結構
指令 |
例子 |
解釋 |
ng-app |
|
初始化應用程序 |
ng-init |
|
初始化數據 |
ng-module |
|
把元素綁定到應用程序 |
ng-repeat |
|
重複HTML元素 |
ng-module |
<form name=’myForm’> <input type=’email’ ng-module=’myText’ name=’myAddress’> <p>點擊</p> {{myForm.myAddress.$valid}} {{ myForm.myAddress.$dirty}} </form> |
將輸入域的值與變量綁定,可以爲應用數據提供狀態值 Invalid:輸入值合法時爲ture dirty:值改變時爲 touched:通過觸屏點擊爲ture error: |
*ngFor |
//數據
|
ngFor用作循環 |
ngSwitch | //定義數據 public score:ang=”1” //使用: <ul [ngSwitch]=”score”> <li *ngSwitchCase=”1”>已支付</li> <li *ngSwitchCase=”2”>未支付</li> <li *ngSwitchCase=”false”>支付失敗</li> </ul> |
|
*ngIf | //定義數據: public flag:boolean=true; //使用 <div *ngIf=”flag”><div> |
用處 |
命令 |
解釋 |
查看angular版本 |
ng version |
|
創建項目 |
ng new demo |
|
運行項目 |
ng serve –open |
|
創建有哪些參數 |
ng g |
|
創建組件 |
ng g component comments/header |
|
服務與依賴注入
依賴注入providers:組件引入外部構建(如服務)的一種機制
服務:實現單一目的的邏輯單元,如日誌服務
服務→實例化→依賴注入→注入→組件
@component({
selector:’hello’,
template:’<p>greeting</p>’,
providers:[loggerService],
})
export class HelloCom1{
private greeting:string;
constructor(logger: loggerService){
this.greeting=’hello angular’;
logger.debug(‘構造函數執行完畢’)
}}
模塊
包括文件模塊和應用模塊
文件模塊:框架代碼以模塊形式組織,包括core核心模塊(變換檢測,依賴注入Component,Directive,ElementRef,Renderer等),comment通用模塊(常用內置指令),forms表單模塊(表單相關組件和指令),http網絡模塊(處理網絡請求)及其他
應用模塊:功能單元以模塊形式主旨,即將組件,指令,服務進行包裝
1.導入
import {Http} from ‘@angular/http’
2.模塊定義
@NgModule({ //模塊聲明
declarations:[AppComponent,SomeDiretive], //包裝指令或組件等
providers:[loggerService], //依賴注入
imports:[OtherModule], //導入其他模塊
bootstrap:[ AppComponent], //設置根組件
exports:[SomeDirective], //導出組件或指令
})
export class AppModule {}
數據處理
pipe管道
類型 | 例子 |
日期轉換 |
定義:public today:any=new Date() 使用:{{today | date : ‘yyyy-MM-dd HH-mm-ss‘}} |
大小寫轉換 |
轉換成大寫:{{data1 | uppercase}} 轉換成小寫:{{data1 | lowercase}} |
小數位數 |
格式:最少整數位數.最少小數位數-最多整數位數 {{data2 | number:1.2-4}} |
對象序列化 | {{ {name:’jennifer’}| json}} |
字符串截取 | {{ ‘jennifer’|slice:0:3}} |
管道鏈 | {{‘jennifer’ | slice:0:3 | uppercase}} |
表單
表單類型 | 關鍵詞 | 例子 |
輸入框 | text | <input type=’text’ /> |
單選 | radio |
<input type='radio' value="男" name="sex" id="sex1" [(ngModel)]="userInfo.userSex"><label for='sex1'>男</label> <input type='radio' value="女" name="sex" id="sex1" [(ngModel)]="userInfo.userSex"><label for='sex1'>女</label> ngModle 綁定Value值,當ngModel值和value值相同,默認被選中 |
多選 | checkbox |
<span *ngFor=’item of userInfo.hobby’> <input type=’checkbox’ [(ngModel)]=’item.checked’ /> </span> 雙向綁定的是check的value,被選中則爲true |
下拉列表 |
select option |
<select name=’’ [(ngModel)]=’item’> <option [value]=’item’ *ngFor=’item of userInfo.cityList’>{{item}}</option> </select> Select裏雙向綁定的是被選中的option的value |
P6(搜索記錄和todolist)
輸出 |
增 | 刪 | |
搜索緩存 |
<input type=”text” [(ngModel)]=”keyword”/> <button (click)=”zengjia()”></button> <ul> <li *ngFor=”let item of arr; let key=index”>{{item}} <button (click)=”delete(key)”>刪除</button></li> </ul> |
public arr:any[]=[]; public keyword:any; zengjia(){//檢測是否存在相同值 if(this.arr.indexOf(this.keyword)==-1){ this.arr.push(this.keyword) } } |
delete(key){ this.arr.splice(key,1) } |
Todolist | |||
P7數據緩存
服務Stourage.service.ts | 根模塊app.module.ts | 組件 | ||||||
1.1創建服務 ng g service services/storage |
2.1引入服務import {StorageService} from './services/storage.service'; |
3.1組件中引入服務 import {StorageService} from '../../services/storage.service'; |
||||||
1.2服務類中的內容
set(key:any,value:any){ localStorage.setItem(key,JSON.stringify(value)); } //從localstorage取出 get(key:any){ return JSON.parse(localStorage.getItem(key)) } //從localstorage移除 remove(key:any){ localStorage.removeItem(key) } |
2.2註冊
@NgModule({ providers: [StorageService], }) |
3.2組件中註冊constructor(public storage:StorageService) { } 3.3組件中使用服務類中的方法 this.storage.set('todolist',this.todoList); ngOnInit() { var localList=this.storage.get('todolist'); this.todoList=localList; } |
Dom操作
獲取Document對象:
import { DOCUMENT } from '@angular/common';
constructor(@Inject(DOCUMENT) private doc: Document) { }
P8ViewChild用於Dom操作和組件方法調用
html:<div #wySlide></div> //1.Dom
ts:
class裏{
private sliderDom: HTMLDivElement; //3.類型聲明
@ViewChild('wySlider', { static: true }) private wySlider: ElementRef; //2.獲取ElementRef
ngOnInit(){
this.sliderDom = this.wySlider.nativeElement; //4.獲取Dom
}}
P9父子組件通信
通信方式 | 父組件中內容 |
子組件中內容 |
子獲取父數據@Input |
public msgFromFather:any=”我是父組件傳給子組件的值” <app-header [childMsg]=”msgFromFather”></app-header> |
import {Import} from ‘@angular/core’; @imprrt() childMsg:any; getMsg(){ console.log(this.childMsg) } |
子執行父方法@Input |
funFromFather(){alert(“父組件方法”)} <app-header [run]=”funFromFather”></app-header> |
import {Import} from ‘@angular/core’; @Input run:any getRun(){ this.run() } |
子獲取整個父組件 |
public msg:any=”首頁” <app-header [home]=”this”></app-header> |
import {Input} from ‘@angular/core’ @Input home:any; getFatherMag(){ alert(this.home.msg) } |
父獲取子數據/方法@ViewChild |
<app-header #header></app-header> import {ViewChild} from ‘@angular/core’ @ViewChild(“header”) box2 getChildMsg(){ return this.box2.msg; } getChildFunc(){ return this.box.run() } |
public msg:any=”子組件的數據” run(){alert(“子組件的方法”)} |
子觸發父方法並傳值(父被動獲取子數據) |
<app-header (outer)=”runParent($event)”></app-header> runParent(e){alert(outer)} |
<button (click)="setParent('傳入值')"></button> import {Output,EventEmitter} from ‘@angular/core’ @Output() private outer=new EventEmitter<string>(); //實例化 setParent(data){this.outer.emit(data)} |
P10生命週期
異步,響應式
異步編程方法 | 服務內容(RequestService) | 組件裏調用 | 解釋 |
回調函數 |
getCallbackData(cb){ setTimeout(() => { var username = "jennifer"; cb(username); },1000); } |
construct(p){public request:RequestService} ngOnInit(){ this.request.getCallbackData( (data) => {console.log(data)} ) } |
cb函數作爲getCallbackData的參數被傳進,然後被異步函數setTimeOut調用 回調函數:將一個函數作爲參數傳入到另一函數 |
Promise |
getPromiseData(){ return new Promise((resolve,reject) => { setTimeout(() => { var username = "jennifer"; resolve(username); },1000); }) } |
construct(p){public request:RequestService} ngOnInit(){ this.request.getPromiseData().then( (data) => {console.log(data)} ) } |
getPromiseData裏的異步函數setTimeOut執行成功後就調用resolve函數 Promise.then()設置resolve()和reject()內容 |
Rxjs |
import {Observable} from 'rxjs'; getRxjsData(){ let steam = new Obervable(observer =>{ setTimeout(() => { var username = "jennifer"; obsever.next(username); observer.error("失敗") },1000); }) }
|
construct(p){public request:RequestService} ngOnInit(){ var rxjs = this.request.getRxjsData(); rxjs.subscribe( (data) => {console.log(data)} ) } |
subscript()設置 |
Rxjs取消訂閱 |
import {Observable} from 'rxjs'; getRxjsData(){ let steam = new Obervable(observer =>{ setTimeout(() => { var username = "jennifer"; obsever.next(username); observer.error("失敗") },3000); }) } |
construct(p){public request:RequestService} ngOnInit(){ var rxjs = this.request.getRxjsData(); var d = rxjs.subscribe( (data) => {console.log(data)} ) setTimeOut(() => {d.unsubscript()},1000) } |
|
Rxjs多次執行 |
import {Observable} from 'rxjs'; getRxjsData(){ let steam = new Obervable(observer =>{ setInterval(() => { var username = "jennifer"; obsever.next(username); observer.error("失敗") },1000); }) } |
construct(p){public request:RequestService} ngOnInit(){ var rxjs = this.request.getRxjsData(); rxjs.subscribe( (data) => {console.log(data)} ) } |
P12請求數據
方式 | 根模塊中app.module.ts | 組件中 | 組件中發出請求 |
get | import {HttpClientModule} from ‘@angular/common/http’; |
import {HttpClient} from ‘@angular/common/http’;(get請求) import
constructor(public http:HttpClient){} |
var api=http://xxx; this.http.get(api).subscribe(response => {console.log(response); }); |
post | import {HttpClientModule} from ‘@angular/common/http’; | constructor(public http:HttpClient){} |
const httpOptions = { headers:new HttpHeaders({‘Content-type’:’application/json’}) } var api=http://xxx/doLogin; this.http.post(api,{username:”張三”,age:”20”},httpOptions).subscribe( response => {console.log(response)}; ); |
jsonp | import {HttpClientModule, httpClientJsonpModule} from ‘@angular/common/http’; |
import {HttpClient} from ‘@angular/common/http’; constructor(public http:HttpClient){} |
var api=http://xxx/doLogin; this.http.jsonp(api,’callback’).subscribe(response =>{console.log(response)}) |
方法 | 內容 | 步驟 | ||
axios | 服務HttpService中使用axios |
1.1安裝 cnpm install axios --save |
1.2新建服務 ng g service services/httpservice 服務中引入axios import axios from ‘axios’ |
1.3服務類中使用axios axiosGet(api){ return new Promise((resolve,reject) => { axios.get(api) .then(function(response){ resolve(response); }) }) } |
根模塊app.moudule.ts |
2.1引入服務類 import {HttpService} from ‘./services/httpservice.service’; |
2.2註冊 @NgModule({ providers:[ HttpService], }) |
||
組件中 |
3.1引入服務類 import {HttpService} from ‘../../services/httpservice.service’; |
3.2實例化 constructor(public httpService: HttpService,){} |
3.3發出請求 var api=http://xxx/doLogin; this. httpService. axiosGet(api).then((data) => { console.log(data) }) |
P13路由
配置理由
根路由模塊中由引入組件 | 根路由模塊中配置路由 | 使用路由 |
import {HomeComponent} from ‘./home/home.component’; import {newsComponent} from ‘./news/news.component’; import {newsContentComponent} from ‘./newsContent/newsContent.component’; |
const routes:Routes = [ {path:’home’,component:HomeComponent}, { path:’news’,component: newsComponent },//靜態路由 { path:’newsContent/:aid’,component: newsContentComponent },//動態路由 {path:’**’,redirectTo:’home’} //默認路由
] |
<h1> <a [routerLink]=”[’/home’]”>首頁</a> <a [routerLink]=”[’/news’]”>新聞</a> </h1> <router-outlet></router-outlet> |
路由傳值(組件切換+傳值)
app.routing.moudules.ts | 傳出數據的組件 | 接受數據組件 | |
get傳值 |
引入組件 import {HomeComponent} from ‘./home/home.component’; import {newsComponent} from ‘./news/news.component’; import {newsContentComponent} from ‘./newsContent/newsContent.component’; 路由配置(靜態) const routes:Routes = [ {path:’home’,component:HomeComponent}, { path:’news’,component: newsComponent }, { path:’newsContent’,component: newsContentComponent }, {path:’**’,redirectTo:’home’} //默認路由 ] |
通過queryParams傳值 <li *ngFor=”let item of list;let key =index”> <a [routerLink]=”[‘/newsContent’]” [queryParams]=”{aid:key}”>{{item}}</a> </li> |
引入ActivityRoute import {ActivatedRoute} from ‘@angular/router’; 聲明 constructor(public route: ActivatedRoute){} 獲取數據 ngOnInit(){ this.route.queryParams.subscribe((data) => { console.log(data) }) } |
動態路由傳值 |
引入組件(同上) 路由配置(動態) const routes:Routes = [ {path:’home’,component:HomeComponent}, //普通路由 { path:’news’,component: newsComponent },//普通路由 { path:’newsContent/:aid’,component: newsContentComponent }, //動態路由 path:’**’,redirectTo:’home’} ] |
<li *ngFor=”let item of list;let key =index”> <a [routerLink]=”[‘/newsContent/’,key]”>{{item}}</a> </li> |
引入ActivityRoute import {ActivatedRoute} from ‘@angular/router’; 聲明 constructor(public route:ActivitedRoute){} 獲取數據 ngOnInit(){ this.route.params.subscribe((data) => {data}) } |
路由跳轉(頁面跳轉+傳值)
方法 | 跳轉前頁面 | 接收數據頁面 |
路由get傳值js跳轉 |
觸發跳轉 <button (click)=” goNewsContent()”></button> |
接受數據組件newsContent引入ActivityRoute並聲明 import {ActivatedRoute} from ‘@angular/router’; constructor(public route: ActivatedRoute){} ngOnInit(){ this.route.queryParams.subscribe((data) => { console.log(data) }) |
引入NavigationExtras import{Router, NavigationExtras} from ‘@angular/router’ construct中初始化 constructor(public router:Router){} 執行跳轉,用NavigationExtras配置傳參 goNewsContent(){ //定義數據 let msg: NavigationExtras = { queryParams:{‘userId’:’123’}, fragment:’anchor’ }; this.router.navigate([‘/news’], msg) } |
||
動態路由的js跳轉 |
觸發跳轉 <button (click)=”goNewsContent()”>js路由跳轉(動態路由)<button> <button (click)=”goHome ()”>js路由跳轉(普通路由)<button> |
接收數據的組件 import {ActivatedRoute} from ‘@angular/router’; constructor(public route:ActivitedRoute){} ngOnInit(){ this.route.params.subscribe((data) => {data}) } |
引入 import {Router} from ‘@angular/router’; 初始化 constructor(public router:Router){} navigate跳轉 goNewsContent(){ this.router.navigate([‘/newsContent/’ ,’1234’]) } goHome(){ this.router.navigate([‘/Home’]) } |
P15嵌套路由(父子路由)
場景:頁面存在父子組件,點擊時加載不同子組件
根路由模塊配置路由app-routing.module.ts | 父組件home | |
創建home的子組件news ng g component component components/home/news 引入組件(縮進) import {HomeComponent} from ‘./home/home.component’; import {newsComponent} from ‘./news/news.component’; 配置嵌套路由 const routes:Routes = [ {path:’home’,component:HomeComponent children:[ { path:’news’,component: newsComponent }, {path:'**',redirectTo:'news'} //默認加載 ] ] |
<a [routerLink]=“['/home/welcome']">加載新聞組件</a> <a [routerLink]=”['/home/welcome']">加載通知組件</a> <div> <router-outlet></router-outlet> </div> |
|
- 創建home的子組件
ng g component component components/home/welcome