Angular7入門總結篇
一、Angular 介紹
- 根據項目數統計
angular(1.x 、2.x 、4.x、5.x、6.x、7.x)
是現在網上使用量最大的框架 -
Angualr
基于TypeScript
和react
、vue
相比,Angular
更適合中大型企業級項目。
目前 2018 年 11 月 25 日
angular
最新版本angular7.x
。根據官方介紹,Angular
每過幾個月 就會更新一個版本。此教程同樣適用于后期更新的Angular8.x
、Angular9.x
學習 Angular 必備基礎
必備基礎:
html
、css
、js
、es6
、Typescript
二、Angular 環境搭建及創建項目
1 環境搭建
1. 安裝 nodejs
安裝
angular
的計算機上面必須安裝最新的nodejs
--注意安裝nodejs
穩定版本
</article>
用
augury
查看component
結構,更方便調試
2.3 目錄結構分析
app目錄(重點)
app
目錄是我們要編寫的代碼目錄。我們寫的代碼都是放在這個目錄。
一個Angular
程序至少需要一個模塊和一個組件。在我們新建項目的時候命令行已經默認生成出來了
-
app.component.ts
:這個文件表示組件, - 組件是
Angular
應用的基本構建模塊,可以理解為一段帶有業務邏輯和數據的Html
我們來看看app.component.ts
中的代碼,并解釋下代碼的意義
2.4 Angular cli
1. 創建新組件 ng generate component component-name
ng g component components/header
指定生成到哪個目錄
該命令會把生成的組件,添加到 src/app/app.module.ts
文件中 @NgModule
的 declarations
列表中聲明
三、angular組件及組件里的模板
3.1 創建angualr組件
1. 創建組件
ng g component components/header
2. 使用組件
<app-header></app-header>
3.2 Angular 綁定數據
1. 數據文本綁定
定義數據幾種方式
<h1>{{title}}</h1>
2. 綁定HTML
this.h="<h2>這是一個 h2 用[innerHTML]來解析</h2>"
<div [innerHTML]="h"></div>
3.3 聲明屬性的幾種方式
-
public
共有(默認) 可以在類里外使用 -
protected
保護類型 只能在當前類和子類中使用 -
private
私有類型 只能在當期類使用
3.4 綁定屬性
用
[]
包裹
<div [id]="id" [title]="msg">調試工具看看我的屬性</div>
3.5 數據循環 *ngFor
*1. ngFor 普通循環
export class HomeComponent implements OnInit {
arr = [{ name: 'poetries', age: 22 }, { name: 'jing' , age: 31}];
constructor() { }
ngOnInit() {
}
}
<ul *ngIf="arr.length>0">
<li *ngFor="let item of arr">{{item.name}}- {{item.age}}</li>
</ul>
2. 循環的時候設置 key
<ul>
<li *ngFor="let item of list;let i = index;"> <!-- 把索引index賦給i -->
{{item}} --{{i}}
</li> </ul>
3. template 循環數據
<ul>
<li template="ngFor let item of list">
{{item}}
</li> </ul>
3.6 條件判斷 *ngIf
<p *ngIf="list.length > 3">這是 ngIF 判斷是否顯示</p>
<p template="ngIf list.length > 3">這是 ngIF 判斷是否顯示</p>
3.7 *ngSwitch
<ul [ngSwitch]="score">
<li *ngSwitchCase="1">已支付</li>
<li *ngSwitchCase="2">訂單已經確認</li> <li *ngSwitchCase="3">已發貨</li>
<li *ngSwitchDefault>無效</li>
</ul>
3.8 執行事件 (click)=”getData()”
<button class="button" (click)="getData()"> 點擊按鈕觸發事件
</button>
<button class="button" (click)="setData()"> 點擊按鈕設置數據
</button>
getData(){ /*自定義方法獲取數據*/ //獲取
alert(this.msg);
}
setData(){
//設置值
this.msg='這是設置的值';
}
3.9 表單事件
<input
type="text"
(keyup)="keyUpFn($event)"/>
<input type="text" (keyup)="keyUpFn($event)"/>
keyUpFn(e){
console.log(e)
}
3.10 雙向數據綁定
<input [(ngModel)]="inputVal">
注意引入:
FormsModule
import {FormsModule} from '@angular/forms'
NgModule({
declarations: [
AppComponent,
HeaderComponent,
FooterComponent,
NewsComponent
],
imports: [
BrowserModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
<!--使用-->
<input type="text" [(ngModel)]="inputValue"/> {{inputValue}}
3. 11 [ngClass]、[ngStyle]
1. [ngClass]:
<div [ngClass]="{'red': true, 'blue': false}">
這是一個 div
</div>
public flag=false;
<div [ngClass]="{'red': flag, 'blue': !flag}">
這是一個 div </div>
public arr = [1, 3, 4, 5, 6];
<ul>
<li *ngFor="let item of arr, let i = index"> <span [ngClass]="{'red': i==0}">{{item}}</span>
</li> </ul>
2. [ngStyle]:
<div [ngStyle]="{'background-color':'green'}">你好 ngStyle</div>
public attr='red';
<div [ngStyle]="{'background-color':attr}">你好 ngStyle</div>
3.12 管道
public today=new Date();
<p>{{today | date:'yyyy-MM-dd HH:mm:ss' }}</p>
其他管道
angular
中的管道(pipe
)是用來對輸入的數據進行處理,如大小寫轉換、數值和日期格式化等
angular
中的管道(pipe
) 以及自定義管道適用于angular4 angualr5 angualr6 angular7
常用的管道(pipe
)有
1. 大小寫轉換
<!--轉換成大寫-->
<p>{{str | uppercase}}</p>
<!--轉換成小寫-->
<p>{{str | lowercase}}</p>
2. 日期格式轉換
<p>
{{today | date:'yyyy-MM-dd HH:mm:ss' }}
</p>
3. 小數位數
接收的參數格式為
{最少整數位數}.{最少小數位數}-{最多小數位數}
<!--保留2~4位小數-->
<p>{{p | number:'1.2-4'}}</p>
4. JavaScript 對象序列化
<p>
{{ { name: 'semlinker' } | json }}
</p>
<!-- Output: { "name": "semlinker" } -->
5. slice
<p>{{ 'semlinker' | slice:0:3 }}</p>
<!-- Output: sem -->
6. 管道鏈
<p>
{{ 'semlinker' | slice:0:3 | uppercase }}
</p>
<!-- Output: SEM -->
7. 自定義管道
自定義管道的步驟:
- 使用
@Pipe
裝飾器定義Pipe
的metadata
信息,如Pipe
的名稱 - 即name
屬性 - 實現
PipeTransform
接口中定義的transform
方法
7.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 WelcomePipe');
}
return "Welcome to " + value;
}
}
7.2 WelcomePipe 使用
<div>
<p ngNonBindable>{{ 'semlinker' | welcome }}</p>
<p>{{ 'semlinker' | welcome }}</p> <!-- Output: Welcome to semlinker -->
</div>
四、Angular 中的服務
4.1 服務
定義公共的方法,使得方法在組件之間共享調用
1. 創建服務命令
ng g service my-new-service
# 創建到指定目錄下面
ng g service services/storage
2. app.module.ts 里面引入創建的服務
// app.module.ts 里面引入創建的服務
import { StorageService } from './services/storage.service';
// NgModule 里面的 providers 里面依賴注入服務
NgModule({
declarations: [
AppComponent,
HeaderComponent,
FooterComponent,
NewsComponent,
TodolistComponent
], imports: [
BrowserModule,
FormsModule
],
providers: [StorageService],
bootstrap: [AppComponent]
})
export class AppModule { }
3. 使用的頁面引入服務,注冊服務
import { StorageService } from '../../services/storage.service';
constructor(private storage: StorageService) {
}
// 使用
addData(){
// alert(this.username);
this.list.push(this.username);
this.storage.set('todolist',this.list);
}
removerData(key){
console.log(key);
this.list.splice(key,1);
this.storage.set('todolist',this.list);
}
五、Dom 操作以及@ViewChild、 執行 css3 動畫
1. Angular 中的 dom 操作(原生 js)
ngAfterViewInit(){
var boxDom:any=document.getElementById('box'); boxDom.style.color='red';
}
2. Angular 中的 dom 操作(ViewChild)
import { Component ,ViewChild,ElementRef} from '@angular/core';
@ViewChild('myattr') myattr: ElementRef;
<div #myattr></div>
ngAfterViewInit(){
let attrEl = this.myattr.nativeElement;
}
3. 父子組件中通過 ViewChild 調用子組件 的方法
調用子組件給子組件定義一個名稱
<app-footer #footerChild></app-footer>
引入
ViewChild
import { Component, OnInit ,ViewChild} from '@angular/core';
ViewChild
和剛才的子組件關聯起來
@ViewChild('footerChild') footer
在父組件中調用子組件方法
run(){
this.footer.footerRun();
}
六、Angular 父子組件以及組件之間通訊
6.1 父組件給子組件傳值-@input
父組件不僅可以給子組件傳遞簡單的數據,還可把自己的方法以及整個父組件傳給子組件
1. 父組件調用子組件的時候傳入數據
<app-header [msg]="msg"></app-header>
2. 子組件引入 Input 模塊
import { Component, OnInit ,Input } from '@angular/core';
3. 子組件中 @Input 接收父組件傳過來的數據
export class HeaderComponent implements OnInit {
@Input() msg:string
constructor() { }
ngOnInit() {
}
}
4. 子組件中使用父組件的數據
<p>
child works!
{{msg}}
</p>
5. 把整個父組件傳給子組件
通過
this
傳遞整個組件實例
<app-header [home]="this"></app-header>
export class HeaderComponent implements OnInit {
@Input() home:any
constructor() { }
ngOnInit() {
}
}
執行父組件方法
this.home.xxx()
6.2 子組件通過@Output 觸發父組件的方法(了解)
1. 子組件引入 Output 和 EventEmitter
import { Component, OnInit ,Input,Output,EventEmitter} from '@angular/core';
2. 子組件中實例化 EventEmitter
@Output() private outer=new EventEmitter<string>(); /*用EventEmitter和output裝飾器配合使用 <string>指定類型變量*/
3. 子組件通過 EventEmitter 對象 outer 實例廣播數據
sendParent(){
// alert('zhixing');
this.outer.emit('msg from child')
}
6.4 非父子組件通訊
- 公共的服務
-
Localstorage
(推薦) Cookie
七、Angular 中的生命周期函數
7.1 Angular中的生命周期函數
- 生命周期函數通俗的講就是組件創建、組件更新、組件銷毀的時候會觸發的一系列的方法。
- 當
Angular
使用構造函數新建一個組件或指令后,就會按下面的順序在特定時刻調用這些 生命周期鉤子方法。 - 每個接口都有唯一的一個鉤子方法,它們的名字是由接口名再加上
ng
前綴構成的,比如OnInit
接口的鉤子方法叫做ngOnInit
.
1. 生命周期鉤子分類
基于指令與組件的區別來分類
指令與組件共有的鉤子
ngOnChanges
ngOnInit
ngDoCheck
ngOnDestroy
組件特有的鉤子
ngAfterContentInit
ngAfterContentChecked
ngAfterViewInit
ngAfterViewChecked
2. 生命周期鉤子的作用及調用順序
1、ngOnChanges
- 當數據綁定輸入屬性的值發生變化時調用
2、ngOnInit
- 在第一次 ngOnChanges
后調用
3、ngDoCheck
- 自定義的方法,用于檢測和處理值的改變
4、ngAfterContentInit
- 在組件內容初始化之后調用
5、ngAfterContentChecked
- 組件每次檢查內容時調用
6、ngAfterViewInit
- 組件相應的視圖初始化之后調用
7、ngAfterViewChecked
- 組件每次檢查視圖時調用
8、ngOnDestroy
- 指令銷毀前調用
3. 首次加載生命周期順序
export class LifecircleComponent {
constructor() {
console.log('00構造函數執行了---除了使用簡單的值對局部變量進行初始化之外,什么都不應該做')
}
ngOnChanges() {
console.log('01ngOnChages執行了---當被綁定的輸入屬性的值發生變化時調用(父子組件傳值的時候會觸發)');
}
ngOnInit() {
console.log('02ngOnInit執行了--- 請求數據一般放在這個里面');
}
ngDoCheck() {
console.log('03ngDoCheck執行了---檢測,并在發生 Angular 無法或不愿意自己檢測的變化時作出反應');
}
ngAfterContentInit() {
console.log('04ngAfterContentInit執行了---當把內容投影進組件之后調用');
}
ngAfterContentChecked() {
console.log('05ngAfterContentChecked執行了---每次完成被投影組件內容的變更檢測之后調用');
}
ngAfterViewInit() : void {
console.log('06 ngAfterViewInit執行了----初始化完組件視圖及其子視圖之后調用(dom操作放在這個里面)');
}
ngAfterViewChecked() {
console.log('07ngAfterViewChecked執行了----每次做完組件視圖和子視圖的變更檢測之后調用');
}
ngOnDestroy() {
console.log('08ngOnDestroy執行了····');
}
//自定義方法
changeMsg() {
this.msg = "數據改變了";
}
}
7.2.7 ngAfterViewInit()--掌握
初始化完組件視圖及其子視圖之后調用。第一 次
ngAfterContentChecked()
之后調用,只調用一次。在這里可以操作DOM
7.2.9 ngOnDestroy()--掌握
當
Angular
每次銷毀指令/組件之前調用并清掃。在這兒反訂閱可觀察對象和分離事件處理器,以防內存泄 漏。在Angular
銷毀指令/組件之前調用。比如:移除事件監聽、清除定時器、退訂Observable
等。
@Directive({
selector: '[destroyDirective]'
})
export class OnDestroyDirective implements OnDestroy {
sayHello: number;
constructor() {
this.sayHiya = window.setInterval(() => console.log('hello'), 1000);
}
ngOnDestroy() {
window.clearInterval(this.sayHiya);
}
}
八、Rxjs 異步數據流編程
8.1 Rxjs介紹
-
RxJS
是一種針對異步數據流編程工具,或者叫響應式擴展編程;可不管如何解釋 RxJS 其目 標就是異步編程,Angular
引入RxJS
為了就是讓異步可控、更簡單。 -
RxJS
里面提供了很多模塊。這里我們主要給大家講RxJS
里面最常用的Observable
和fromEvent
目前常見的異步編程的幾種方法:
- 回調函數
- 事件監聽/發布訂閱
Promise
Rxjs
8.3 Rxjs unsubscribe 取消訂閱
Promise
的創建之后,動作是無法撤回的。Observable
不一樣,動作可以通過unsbscribe()
方法中途撤回,而且Observable
在內部做了智能的處理.
Promise 創建之后動作無法撤回
九、路由
// 引入組件
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/:id', component: NewscontentComponent},
{
path: '',
redirectTo: '/home',
pathMatch: 'full'
} ];