日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

也许是全网最全的 Angular 新手入门指南

發布時間:2023/12/16 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 也许是全网最全的 Angular 新手入门指南 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • Angular概述
      • Angular程序架構
      • Angular優勢
      • @angular/cli腳手架
      • 文件加載順序
      • 項目目錄結構
    • Angular模塊
      • @NgModule 裝飾器
      • 內置模塊
      • 自定義模塊
      • 模塊的tips
    • Angular組件
      • @Component 元數據
      • 數據綁定
      • 臟值檢測
      • 父子組件通訊
      • 投影組件
    • Angular指令
      • 內置屬性型指令
      • 內置結構型指令
      • 指令事件樣式綁定
    • Angular生命周期
    • Angular路由
      • 路由基本配置
      • 激活路由
      • 路由參數
      • 路由懶加載
    • Angular服務
      • @Injectable()裝飾器
      • 依賴注入
    • Angular 管道
      • 內置管道
      • 自定義管道
    • Angular操作DOM
      • 原生JS操作
      • ElementRef
      • ViewChild
      • Renderer2
    • Angular網絡請求
      • HttpClient
      • 攔截器
    • Angular表單
      • 模版驅動表單
      • 響應式表單
      • 表單驗證
      • 動態表單
    • Angular CDK

Angular概述

Angular 是谷歌開發的一款開源的 web 前端框架,基于 TypeScript 。

和 react 與 vue 相比, Angular 更適合中大型企業級項目。

Angular程序架構

Angular優勢

  • 可伸縮性:基于RxJS 、immutable.js和其他推送模型,能適應海量數據需求
  • 跨平臺:漸進式應用(高性能、離線使用、免安裝),原生(Ionic),桌面端
  • 生產率:模版(通過簡單而強大的模版語法,快速創建UI視圖),CLI(快速進入構建環節、添加組件和測試,然后立即部署)
  • 測試:單元測試(支持Karma、Jasmine等工具進行單元測試),端到端測試(支持Protractor等工具進行端到端測試)

@angular/cli腳手架

  • ng new 新建項目
    • ——routing 配置路由
    • ——style=css|scss|less 配置css樣式
  • ng serve 啟動項目
    • ——port 4200 端口號,默認4200
    • ——open 自動打開瀏覽器
  • ng build 打包項目
    • ——aot 預編譯
    • ——prod 壓縮打包
    • ——base-href=/static/
  • ng generate 創建模塊/組件/服務
    • module ——routing 創建模塊
    • component 創建組件
    • service / 創建服務

    文件加載順序

    main.ts => app.module.ts => app.component.ts => index.html => app.component.html

    項目目錄結構

    |-- project|-- .editorconfig // 用于在不同編輯器中統一代碼風格|-- .gitignore // git中的忽略文件列表|-- README.md // markdown格式的說明文件|-- angular.json // angular的配置文件|-- browserslist // 用于配置瀏覽器兼容性的文件|-- karma.conf.js // 自動化測試框架Karma的配置文件|-- package-lock.json // 依賴包版本鎖定文件|-- package.json // npm的包定義文件|-- tsconfig.app.json // 用于app項目的ts配置文件|-- tsconfig.json // 整個工作區的ts配置文件|-- tsconfig.spec.json // 用于測試的ts配置文件|-- tslint.json // ts的代碼靜態掃描配置|-- e2e // 自動化集成測試目錄|-- src // 源代碼目錄|-- src // 源代碼目錄|-- favicon.ico // 收藏圖標|-- index.html // 單頁應用到宿主HTML|-- main.ts // 入口 ts 文件|-- polyfills.ts // 用于不同瀏覽器的兼容腳本加載|-- styles.css // 整個項目的全局css|-- test.ts // 測試入口|-- app // 工程源碼目錄|-- assets // 資源目錄|-- environments // 環境配置|-- environments.prod.ts // 生產環境|-- environments.ts // 開發環境

    Angular模塊

    在 app.module.ts 中定義 AppModule,這個根模塊會告訴 Angular 如何組裝應用。

    @NgModule 裝飾器

    @NgModule 接受一個元數據對象,告訴 Angular 如何編譯和啟動應用

    設計意圖

    • 靜態的元數據(declarations)
    • 運行時的元數據(providers)
    • 組合與分組(imports 和 exports)

    元數據

    • declarations 數組:模塊擁有的組件、指令或管道,注意每個組件/指令/管道只能在一個模塊中聲明
    • providers 數組: 模塊中需要使用的服務
    • imports 數組:導入本模塊需要的依賴模塊,注意是模塊
    • exports 數組: 暴露給其他模塊使用的組件、指令或管道等
    • bootstrap 數組:指定應用的主視圖(稱為根組件)通過引導根 AppModule 來啟動應用,即項目剛加載時選擇讀哪個組件
    • entryComponents 數組:一般用于動態組件

    內置模塊

    常用的有:核心模塊、通用模塊、表單模塊、網絡模塊等

    自定義模塊

    當項目比較小的時候可以不用自定義模塊

    但是當項目非常龐大的時候,把所有的組件都掛載到根模塊里面就不太合適了

    所以可以使用自定義模塊來組織項目,并且通過自定義模塊可以實現路由的懶加載

    模塊的tips

    導入其他模塊時,需要知道使用該模塊的目的

    • 如果是組件,那么需要在每一個需要的模塊中都進行導入
    • 如果是服務,那么一般來說在根模塊導入一次即可

    需要在每個需要的模塊中進行導入的

    • CommonModule : 提供綁定、*ngIf 和 *ngFor 等基礎指令,基本上每個模塊都需要導入它
    • FormsModule / ReactiveFormsModule : 表單模塊需要在每個需要的模塊導入
    • 提供組件、指令或管道的模塊

    只在根模塊導入一次的

    • HttpClientModule / BrowerAnimationsModule NoopAnimationsModule
    • 只提供服務的模塊

    Angular組件

    • 組件是 Angular 的核心,是 Angular 應用中最基本的 UI 構造塊,控制屏幕上被稱為視圖的一小片區域
    • 組件必須從屬于某個 NgModule 才能被其他組件或應用使用
    • 組件在 @NgModule 元數據的 declarations 字段中引用

    @Component 元數據

    • selector :選擇器,選擇相匹配的HTML里的指令模版
    • templateUrl :將選擇器中匹配的指令同級替換成值的模版
    • template :內嵌模版,直接可以在里面寫HTML模版
    • styleUrls :對應模版的樣式,為一個數組,可以引入多個css樣式控制組件
    • encapsulation:組件樣式封裝策略
    @Component({selector: 'app-xxx',templateUrl: 'XXX',styleUrls: ['XXX'],encapsulation:ViewEncapsulation.Emulated // 不寫則默認該值,表示該組件樣式只作用于組件本身,不影響全局樣式,在 head 中生成單獨的 style 標簽 })

    數據綁定

    • 數據綁定 {{data}}

    • 屬性綁定 [id]="id",其中[class.樣式類名]=“判斷表達式”是在應用單個class樣式時的常用技巧

    • 事件綁定 (keyup)="keyUpFn($event)"

    • 樣式綁定可以用 :host 這樣一個偽類選擇器,綁定的樣式作用于組件本身

    • 雙向數據綁定 [(ngModel)]

      // 注意引入:FormsModule import { FormsModule } from '@angular/forms';<input type="text" [(ngModel)]="inputValue"/> {{inputValue}}// 其實是一個語法糖 [ngModel]="username" (ngModelChange)="username = $event"

    臟值檢測

    臟值檢測:當數據改變時更新視圖(DOM)

    如何進行檢測:檢測兩個狀態值(當前狀態和新狀態)

    何時觸發臟值檢測:瀏覽器事件(click、mouseover、keyup等)、setTimeout()或setInterval()、HTTP請求

    Angular 有兩種變更檢測策略:Default 和 OnPush

    可以通過在@Component元數據中設置changeDetection: ChangeDetectionStrategy.OnPush進行切換

    Default:

    優點:每一次有異步事件發生,Angular 都會觸發變更檢測,從根組件開始遍歷其子組件,對每一個組件都進行變更檢測,對dom進行更新。

    缺點:有很多組件狀態沒有發生變化,無需進行變更檢測。如果應用程序中組件越多,性能問題會越來越明顯。

    OnPush:

    優點:組件的變更檢測完全依賴于組件的輸入(@Input),只要輸入值不變就不會觸發變更檢測,也不會對其子組件進行變更檢測,在組件很多的時候會有明顯的性能提升。

    缺點:必須保證輸入(@Input)是不可變的(可以用Immutable.js解決),每一次輸入變化都必須是新的引用。

    父子組件通訊

    父組件給子組件傳值 @input

    父組件不僅可以給子組件傳遞簡單的數據,還可把自己的方法以及整個父組件傳給子組件。

    // 父組件調用子組件的時候傳入數據 <app-header [msg]="msg"></app-header>// 子組件引入 Input 模塊 import { Component, OnInit ,Input } from '@angular/core';// 子組件中 @Input 裝飾器接收父組件傳過來的數據 export class HeaderComponent implements OnInit {@Input() msg:stringconstructor() { }ngOnInit() { } }// 子組件中使用父組件的數據 <h2>這是頭部組件--{{msg}}</h2>

    **子組件觸發父組件的方法 @Output **

    // 子組件引入 Output 和 EventEmitter import { Component,OnInit,Input,Output,EventEmitter} from '@angular/core';// 子組件中實例化 EventEmitter // 用 EventEmitter 和 @Output 裝飾器配合使用 <string> 指定類型變量 @Output() private outer=new EventEmitter<string>();// 子組件通過 EventEmitter 對象 outer 實例廣播數據 sendParent(){this.outer.emit('msg from child') }// 父組件調用子組件的時候,定義接收事件,outer 就是子組件的 EventEmitter 對象 outer <app-header (outer)="runParent($event)"></app-header>// 父組件接收到數據會調用自己的 runParent, 這個時候就能拿到子組件的數據 // 接收子組件傳遞過來的數據runParent(msg:string){alert(msg); }

    父組件通過 ViewChild 主動調用子組件DOM和方法

    // 給子組件定義一個名稱 <app-footer #footerChild></app-footer>// 引入 ViewChild import { Component, OnInit ,ViewChild} from '@angular/core';// ViewChild 和子組件關聯起來 @ViewChild('footerChild') footer;// 調用子組件 run(){this.footer.footerRun(); }

    投影組件

    由于組件過度嵌套會導致數據冗余和事件傳遞,因此引入投影組件的概念

    投影組件 ng-content 作為一個容器組件使用

    主要用于組件動態內容的渲染,而這些內容沒有復雜的業務邏輯,也不需要重用,只是一小部分 HTML 片段

    使用 ng-content 指令將父組件模板中的任意片段投影到它的子組件上

    組件里面的 ng-content 部分可以被組件外部包裹的元素替代

    // 表現形式: <ng-content select="樣式類/HTML標簽/指令"></ng-content><ng-content select="[appGridItem]"></ng-content>

    select 表明包含 appGridItem 的指令的元素才能投影穿透過來


    Angular指令

    指令可以理解為沒有模版的組件,它需要一個宿主元素(Host)

    推薦使用方括號 [] 指定 Selector,使它變成一個屬性

    @Directive({ selector: '[appGridItem]' })

    內置屬性型指令

    NgClass

    ngClass 是自由度和拓展性最強的樣式綁定方式

    <div [ngClass]="{'red': true, 'blue': false}">這是一個 div </div>

    NgStyle

    ngStyle由于是嵌入式樣式,因此可能會覆蓋掉其他樣式,需謹慎

    <div [ngStyle]="{'background-color':'green'}">你好 ngStyle</div>

    NgModel

    // 注意引入:FormsModule import { FormsModule } from '@angular/forms';<input type="text" [(ngModel)]="inputValue"/> {{inputValue}}

    內置結構型指令

    ngIf

    ngIf 根據表達式是否成立,決定是否展示 DOM 標簽

    <p *ngIf="list.length > 3">這是 ngIF 判斷是否顯示</p>

    ngIf else

    <div *ngIf="show else ElseContent">這是 ngIF 內容</div> <ng-template #ElseContent><h2>這是 else 內容</h2> </ng-template>// 結構性指令都依賴于 ng-template,*ngIf 實際上就是 ng-template 指令的 [ngIf] 屬性。

    ngFor

    <ul><li *ngFor="let item of list;let i = index;">{{item}} --{{i}}</li> </ul>

    ngSwitch

    <ul [ngSwitch]="score"><li *ngSwitchCase="1">已支付</li><li *ngSwitchCase="2">已確認</li><li *ngSwitchCase="3">已發貨</li><li *ngSwitchDefault>已失效</li> </ul>

    指令事件樣式綁定

    @HostBinding 綁定宿主的屬性或者樣式

    @HostBinding('style.display') display = "grid";// 用樣式綁定代替rd2的 this.setStyle('display','grid');

    @HostListener 綁定宿主的事件

    @HostListener('click',['$event.target'])// 第一個參數是事件名,第二個是事件攜帶參數

    Angular生命周期

    生命周期函數通俗的講就是組件創建、組件更新、組件銷毀的時候會觸發的一系列的方法

    當 Angular 使用構造函數新建一個組件或指令后,就會按下面規定的順序在特定時刻調用生命周期鉤子

    • constructor :構造函數永遠首先被調用,一般用于變量初始化以及類實例化

    • ngOnChanges :被綁定的輸入屬性變化時被調用,首次調用一定在 ngOnInit 之前。輸入屬性發生變化是觸發,但組件內部改變輸入屬性是不會觸發的。注意:如果組件沒有輸入,或者使用它時沒有提供任何輸入,那么框架就不會調用 ngOnChanges

    • ngOnInit :組件初始化時被調用,在第一輪 ngOnChanges 完成之后調用,只調用一次。使用 ngOnInit 可以在構造函數之后馬上執行復雜的初始化邏輯,同時在 Angular 設置完輸入屬性之后,可以很安全的對該組件進行構建

    • ngDoCheck :臟值檢測時調用,在變更檢測周期中 ngOnChanges 和 ngOnInit 之后

      • ngAfterContentInit :內容投影ng-content完成時調用,只在第一次 ngDoCheck 之后調用

      • ngAfterContentChecked: 每次完成被投影組件內容的變更檢測之后調用(多次)

      • ngAfterViewInit :組件視圖及子視圖初始化完成時調用,只在第一次 ngAfterContentChecked 調用一次

      • ngAfterViewChecked: 檢測組件視圖及子視圖變化之后調用(多次)

    • ngOnDestroy 當組件銷毀時調用,可以反訂閱可觀察對象和分離事件處理器,以防內存泄漏


    Angular路由

    路由(導航)本質上是切換視圖的一種機制,路由的導航URL并不真實存在

    Angular 的路由借鑒了瀏覽器URL變化導致頁面切換的機制

    Angular 是單頁程序,路由顯示的路徑不過是一種保存路由狀態的機制,這個路徑在 web 服務器上不存在

    路由基本配置

    /*** 在功能模塊中定義子路由后,只要導入該模塊,等同于在根路由中直接定義* 也就是說在 AppModule 中導入 HomeModule 的時候,* 由于 HomeModule 中導入了 HomeRouting Module* 在 HomeRoutingModule 中定義的路由會合并到根路由表* 相當于直接在根模塊中定義下面的數組。* const routes = [{* path: 'home',* component: HomeContainerComponent* }]*/const routes: Routes = [{path: 'home', component: HomeComponent},{path: 'news', component: NewsComponent},{path: 'newscontent/:id', component: NewscontentComponent}, // 配置動態路由{path: '',redirectTo: '/home', // 重定向pathMatch: 'full'},//匹配不到路由的時候加載的組件 或者跳轉的路由{path: '**', /*任意的路由*/// component:HomeComponentredirectTo:'home'} ]@NgModule({/*** 根路由使用 `RouterModule.forRoot(routes)` 形式。* 而功能模塊中的路由模塊使用 `outerModule.forChild(routes)` 形式。* 啟用路由的 debug 跟蹤模式,需要在根模塊中設置 `enableTracing: true`*/imports: [RouterModule.forRoot(routes, { enableTracing: true })],exports: [RouterModule] }) export class AppRoutingModule { }

    激活路由

    找到 app.component.html 根組件模板,配置 router-outlet

    通過模版屬性訪問路由,即路由鏈接 routerLink

    <h1><a [routerLink]="['/home']">首頁</a><a [routerLink]="['/home',tab.link]">首頁</a><!-- 路徑參數 --><a [routerLink]="['/home',tab.link,{name:'val1'}]">首頁</a> <!-- 路徑對象參數 --><a [routerLink]="['/home']" [queryParams]="{name:'val1'}">首頁</a> <!-- 查詢參數 --> </h1> <router-outlet></router-outlet> <!-- 路由插座,占位標簽 --> <!--路由顯示的內容是插入到 router-outlet 的同級的下方節點而不是在 router-outlet 中包含 --> <!--當事件處理或者達到某個條件時,可以使用手動跳轉this.router.navigate(['home']); this.router.navigate(['home',tab.link]); this.router.navigate(['home',tab.link,{name:'val1'}]); this.router.navigate(['home'],{queryParams:{name:'val1'}}); -->

    控制路由激活狀態的樣式 routerLinkActive

    <h1><a routerLink="/home" routerLinkActive="active">首頁</a><a routerLink="/news" routerLinkActive="active">新聞</a> </h1><h1><a [routerLink]="[ '/home' ]" routerLinkActive="active">首頁</a><a [routerLink]="[ '/news' ]" routerLinkActive="active">新聞</a> </h1>.active{color:red; }

    路由參數

    路徑參數讀取

    this.route.paramsMap.subscribe(params => {...})

    查詢參數讀取

    this.route.queryParamsMap.subscribe(params => {...})

    路由傳遞一個參數及其接收方法:

    傳遞參數:path:’info/:id’

    接收參數:

    constructor(private routerInfo: ActivatedRoute){} ngOnInit(){this.routerInfo.snapshot.params['id'] }

    路由傳遞多個參數及其接收方法:

    傳遞:[queryParams]=‘{id:1,name:‘crm’}’

    接收參數:

    constructor(private routerInfo: ActivatedRoute){} ngOnInit(){this.routerInfo.snapshot.params['id']this.routerInfo.snapshot.params['name'] }

    路由懶加載

    懶加載子模塊,子模塊需要配置路由設置啟動子模塊 loadChildren

    const routes: Routes = [{path:'user',loadChildren:'./module/user/user.module#UserModule' },{path:'product',loadChildren:'./module/product/product.module#ProductModule'},{path:'article',loadChildren:'./module/article/article.module#ArticleModule'},{path:'**',redirectTo:'user'} ];// 上面好像會報錯 Error find module // 配置懶加載 const routes: Routes = [{path:'user',loadChildren:()=>import('./module/user/user.module').then(mod=>mod.UserModule)},{path:'article',loadChildren:()=>import('./module/article/article.module').then(mod=>mod.ArticleModule)},{path:'product',loadChildren:()=>import('./module/product/product.module').then(mod=>mod.ProductModule)},{path:'**',redirectTo:'user'} ];

    Angular服務

    組件不應該直接獲取或保存數據,應該聚焦于展示數據,而把數據訪問的職責委托給某個服務

    獲取數據和視圖展示應該相分離,獲取數據的方法應該放在服務中

    類似 VueX,全局的共享數據(通用數據)及非父子組件傳值、共享數據放在服務中

    組件之間相互調用各組件里定義的方法

    多個組件都用的方法(例如數據緩存的方法)放在服務(service)里

    import { Injectable } from '@angular/core'; @Injectable({providedIn: 'root', }) export class HeroService {aa = 'abc';constructor(){ }ngOnInit(){ } }import { HeroService } from '../../../services/hero/hero.service'; export class AComponent implements OnInit{constructor(private heroService : HeroService) {} //實例化ngOnInit(){console.log(this.heroService.aa)} }

    @Injectable()裝飾器

    在 Angular 中,要把一個類定義為服務,就要用 @Injectable() 裝飾器來提供元數據,以便讓 Angular 把它作為依賴注入到組件中。

    同樣,也要使用 @Injectable () 裝飾器來表明一個組件或其它類(比如另一個服務、管道或 NgModule)擁有一個依賴。

    @Injectable () 裝飾器把這個服務類標記為依賴注入系統的參與者之一,它是每個 Angular 服務定義中的基本要素。

    在未配置好 Angular 的依賴注入器時,Angular 實際上無法將它注入到任何位置。

    @Injectable () 裝飾器具有一個名叫 providedIn 的元數據選項,providedIn 設置為 'root',即根組件中,那么該服務就可以在整個應用程序中使用了。

    providedIn 提供這些值:‘root' 、'platform' 、'any' 、null

    對于要用到的任何服務,必須至少注冊一個提供者。

    服務可以在自己的元數據中把自己注冊為提供者,可以讓自己隨處可用,也可以為特定的模塊或組件注冊提供者。

    要注冊提供者,就要在服務的 @Injectable () 裝飾器中提供它的元數據,或者在 @NgModule () 或 @Component () 的元數據中。

    在組件中提供服務時,還可以使用 viewProdivers,viewProviders 對子組件樹不可見

    可以使用不同層級的提供者來配置注入器,也表示該服務的作用范圍

    • Angular 創建服務默認采用的方式:在服務本身的 @Injectable () 裝飾器中

    • 該服務只在某服務中使用:在 NgModule 的 @NgModule () 裝飾器中

    • 該服務在某組件中使用:在組件的 @Component () 裝飾器中

    依賴注入

    在項目中,有人提供服務,有人消耗服務,而依賴注入的機制提供了中間的接口,并替消費者創建并初始化處理

    消費者只需要知道拿到的是完整可用的服務就好,至于這個服務內部的實現,甚至是它又依賴了怎樣的其他服務,都不需要關注。

    Angular 通過 service共享狀態,而這些管理狀態和數據的服務便是通過依賴注入的方式進行處理的

    Angular 的 service 的本質就是依賴注入,將service作為一個Injector注入到component中

    歸根到底,很多時候我們創建服務,是為了維護公用的狀態和數據,通過依賴注入的方式來規定哪些組件可共享

    正是因為 Angular 提供的這種依賴注入機制,才能在構造函數中直接聲明實例化

    constructor(private heroService : HeroService) {} // 依賴注入

    先看一下 Angular 中 TS 單文件的注入

    // 首先寫 @injectable 我們需要注入的東西,比如說 product @Injectable() class Product {constructor(private name: string,private color: string,private price: number,) { } }class PurchaseOrder {constructor(private product: Product){ } }export class HomeGrandComponent implements OnInit {constructor() { }ngOnInit() {// 構造一個 injector 用 create 方法 里面 providers 數組中寫我們需要構造的東西const injector = Injector.create({providers: [{provide: Product,// 構造 Product 在 useFactory 中就會把上面定義的 product 注入到這里useFactory: () => {return new Product('大米手機', '黑色', 2999);},deps: []},{provide: PurchaseOrder,deps: [Product]},{provide: token,useValue: { baseUrl: 'http://local.dev' }}]}); console.log('injector獲取product', injector.get(PurchaseOrder).getProduct);console.log(injector.get(token));}

    再看一下Angular 中 module 模塊的注入

    // .service.ts 中 @Injectable () 依賴注入 @Injectable() export class HomeService {imageSliders: ImageSlider[] = [{imgUrl:'',link: '',caption: ''}]getBanners() {return this.imageSliders;} }// 使用模塊對應的.module.ts 中 @NgModule({declarations: [HomeDetailComponent,],providers:[HomeService], // 在 providers 直接寫對應服務,直接將服務注入模塊imports: [SharedModule, HomeRoutingModule] })

    不管是在組件內還是在模塊內,我們使用 providers 的時候,就是進行了一次依賴注入的注冊和初始化

    其實模塊類(NgModule)也和組件一樣,在依賴注入中是一個注入器,作為容器提供依賴注入的接口

    NgModule 使我們不需要在一個組件中注入另一個組件,通過模塊類(NgModule)可以進行獲取和共享


    Angular 管道

    Angular 管道是編寫可以在 HTML 組件中聲明的顯示值轉換的方法

    管道將數據作為輸入并將其轉換為所需的輸出

    管道其實就是過濾器,用來轉換數據然后顯示給用戶

    管道將整數、字符串、數組和日期作為輸入,用 | 分隔,然后根據需要轉換格式,并在瀏覽器中顯示出來

    在插值表達式中,可以定義管道并根據情況使用

    在 Angular 應用程序中可以使用許多類型的管道

    內置管道

    • String -> String
      • UpperCasePipe 轉換成大寫字符
      • LowerCasePipe 轉換成小寫字符
      • TitleCasePipe 轉換成標題形式,第一個字母大寫,其余小寫
    • Number -> String
      • DecimalPipe 根據數字選項和區域設置規則格式化值
      • PercentPipe 將數字轉換為百分比字符串
      • CurrencyPipe 改變人名幣格式
    • Object -> String
      • JsonPipe 對象序列化
      • DatePipe 日期格式轉換
    • Tools
      • SlicePipe 字符串截取
      • AsyncPipe 從異步回執中解出一個值
      • I18nPluralPipe 復數化
      • I18nSelectPipe 顯示與當前值匹配的字符串

    使用方法

    <div>{{ 'Angular' | uppercase }}</div> <!-- Output: ANGULAR --><div>{{ data | date:'yyyy-MM-dd' }}</div> <!-- Output: 2022-05-17 --><div>{{ { name: 'ccc' } | json }}</div> <!-- Output: { "name": "ccc" } --><!-- 管道可以接收任意數量的參數,使用方式是在管道名稱后面添加: 和參數值若需要傳遞多個參數則參數之間用冒號隔開 --><!-- 可以將多個管道連接在一起,組成管道鏈對數據進行處理 --> <div>{{ 'ccc' | slice:0:1 | uppercase }}</div>

    自定義管道

    管道本質上就是個類,在這個類里面去實現 PipeTransfrom 接口的 transform 這個方法

    • 使用 @Pipe 裝飾器定義 Pipe 的 metadata 信息,如 Pipe 的名稱 - 即 name 屬性
    • 實現 PipeTransform 接口中定義的 transform 方法
    // 引入PipeTransform是為了繼承transform方法 import { Pipe, PipeTransform } form '@angular/core'; // name屬性值慣用小駝峰寫法, name的值為html中 | 后面的名稱 @Pipe({ name: 'sexReform' }) export class SexReformPipe implements PipeTransform {transform(value: string, args?: any): string {// value的值為html中 | 前面傳入的值, args為名稱后傳入的參數switch(value){case 'male': return '男';case 'female': return '女';default: return '雌雄同體';} } }// demo.component.ts export Class DemoComponent {sexValue = 'female'; }// demo.component.html <span>{{ sexValue | sexReform }}</span>// 瀏覽器輸出// 管道可以鏈式使用,還可以傳參 <span> {{date | date: 'fullDate' | uppercase}} </span> // 每一個自定義管道都需要實現 PipeTransform 接口,這個接口非常簡單,只需要實現 transform 方法即可。 // transform()方法參數格式 - transform(value: string, args1: any, args2?: any): // value為傳入的值(即為需要用此管道處理的值, | 前面的值); // args 為傳入的參數(?:代表可選); // html 中使用管道格式 - {{ 數據 | 管道名 : 參數1 : 參數2 }} // 與 component 一樣,pipe 需要先在 declarations 數組中聲明后使用

    Angular操作DOM

    原生JS操作

    ngAfterViewInit(){var boxDom:any=document.getElementById('box');boxDom.style.color='red'; }

    ElementRef

    ElementRef 是對視圖中某個原生元素的包裝類

    因為 DOM 元素不是 Angular 中的類,所以需要一個包裝類以便在 Angular 中使用和標識其類型

    ElementRef 的背后是一個可渲染的具體元素。在瀏覽器中,它通常是一個 DOM 元素

    class ElementRef<T> {constructor(nativeElement: T)nativeElement: T //背后的原生元素,如果不支持直接訪問原生元素,則為 null(比如:在 Web Worker 環境下運行此應用的時候)。 }

    當需要直接訪問 DOM 時,請把本 API 作為最后選擇 。優先使用 Angular 提供的模板和數據綁定機制

    如果依賴直接訪問 DOM 的方式,就可能在應用和渲染層之間產生緊耦合。這將導致無法分開兩者,也就無法將應用發布到 Web Worker 中

    ViewChild

    使用模板和數據綁定機制,使用 @viewChild

    // 模版中給 DOM 起一個引用名字,以便可以在組件類或模版中進行引用 <div #myattr></div>// 引入 ViewChild import { ViewChild,ElementRef } from '@angular/core';// 用 ViewChild 綁定 DOM @ViewChild('myattr') myattr: ElementRef;// 在 ngAfterViewInit 生命周期函數里可以很安全的獲取 ViewChild 引用的 DOM ngAfterViewInit(){let attrEl = this.myattr.nativeElement; }

    父組件中可以通過 ViewChild 調用子組件的方法

    // 給子組件定義一個名稱 <app-footer #footerChild></app-footer>// 引入 ViewChild import { Component, OnInit ,ViewChild} from '@angular/core';// ViewChild 和子組件關聯起來 // 如果想引用模版中的 Angular 組件,ViewChild 中可以使用引用名,也可以使用組件類型 @ViewChild('footerChild') footer;// @ViewChild('imageSlider', { static: true }) // static指定是動態還是靜態,在*ngFor或者*ngIf中是動態,否則即為靜態,動態為 true// 調用子組件 run(){this.footer.footerRun(); }

    引用多個模版元素,可以用@ViewChildren,在ViewChildren中可以使用引用名

    或者使用 Angular 組件/指令的類型,聲明類型為 QueryList<?>

    <img#img*ngFor="let slider of sliders"[src]="slider.imgUrl"[alt]="slider.capiton" >// 使用 ViewChildren 引用獲取 @ViewChildren(’img‘);// 使用類型引用獲取 imgs: QueryList<ElementRef>;

    Renderer2

    Renderer2 是 Angular 提供的操作 element 的抽象類,使用該類提供的方法,能夠實現在不直接接觸 DOM 的情況下操作頁面上的元素。

    Renderer2 的常用方法:

    • addClass /removeClass 在 directive 的宿主元素添加或刪除 class
    import { Directive, Renderer2, ElementRef, OnInit } from '@angular/core';@Directive({selector: '[testRenderer2]' })export class TestRenderer2Directive implements OnInit {constructor(private renderer: Renderer2, private el: ElementRef) {} // 實例化ngOnInit() {this.renderer.addClass(this.el.nativeElement, 'test-renderer2');// this.renderer.removeClass(this.el.nativeElement, 'old-class');} }
    • createElement /appendChild/createText 創建 DIV 元素,插入文本內容,并將其掛載到宿主元素上
    import { Directive, Renderer2, ElementRef, OnInit } from '@angular/core';constructor(private renderer: Renderer2, private el: ElementRef) {}ngOnInit() {const div = this.renderer.createElement('div');const text = this.renderer.createText('Hello world!');this.renderer.appendChild(div, text);this.renderer.appendChild(this.el.nativeElement, div); }
    • setAttribute /removeAttribute 在宿主元素上添加或刪除 attribute
    import { Directive, Renderer2, ElementRef, OnInit } from '@angular/core';constructor(private renderer: Renderer2, private el: ElementRef) {}ngOnInit() {this.renderer.setAttribute(this.el.nativeElement, 'aria-hidden', 'true'); }
    • setStyle /removeStyle 在宿主元素上添加 inline-style
    import { Directive, Renderer2, ElementRef, OnInit } from '@angular/core';constructor(private renderer: Renderer2, private el: ElementRef) {}ngOnInit() {this.renderer.setStyle(this.el.nativeElement,'border-left','2px dashed olive'); }

    移除 inline-style :

    constructor(private renderer: Renderer2, private el: ElementRef) {}ngOnInit() {this.renderer.removeStyle(this.el.nativeElement, 'border-left'); }
    • setProperty 設置宿主元素的 property 的值
    constructor(private renderer: Renderer2, private el: ElementRef) {}ngOnInit() {this.renderer.setProperty(this.el.nativeElement, 'alt', 'Cute alligator'); }

    直接操作DOM,Angular不推薦。盡量采用 @viewChild 和 renderer2 組合,Angular推薦使用 constructor(private rd2: Renderer2) {} 依賴注入,

    import {Component,OnInit,Renderer2,ViewChild, } from '@angular/core'; import { AboxItemComponent } from './abox-item/abox-item.component';@Component({selector: 'app-abox',templateUrl: './abox.component.html',styleUrls: ['./abox.component.less'], }) export class AboxComponent implements OnInit {private container;activeIndex: number;@ViewChild('containers') containers: any;constructor(private rd2: Renderer2) {}ngOnInit(): void {}ngAfterViewInit(): void {this.container = this.containers.nativeElement;this.initCarouselWidth();}initCarouselWidth() {this.rd2.setStyle(this.container, 'width', '100px');} }

    Angular網絡請求

    HttpClient

    需導入 HttpClientModule ,只在根模塊中導入,并且整個應用只需導入一次,不用在其他模塊導入

    在構造函數中注入HttpClient,get/post方法對應HTTP方法,這些方法是泛型的,可以直接把返回的JSON轉換成對應類型。若是不規范的請求,使用request方法

    返回的值是 Observable,必須訂閱才會發送請求,否則不會發送

    get 請求數據

    // 在 app.module.ts 中引入 HttpClientModule 并注入 import {HttpClientModule} from '@angular/common/http'; imports: [BrowserModule,HttpClientModule ]// 在用到的地方引入 HttpClient 并在構造函數聲明 import {HttpClient} from "@angular/common/http"; constructor(private http: HttpClient,private cd: ChangeDetectorRef) { } // 依賴注入// get 請求數據 var api = "http://baidu.com/api/productlist"; this.http.get(api).subscribe(response => {console.log(response);this.cd.markForCheck()// 如果改變了臟值檢測的變更原則 changeDetection: ChangeDetectionStrategy.OnPush// 則需要使用 this.cd.markForCheck() 手動提醒 Angular 這里需要進行臟值檢測 });

    post 提交數據

    // 在 app.module.ts 中引入 HttpClientModule 并注入 import {HttpClientModule} from '@angular/common/http'; imports: [BrowserModule,HttpClientModule ]// 在用到的地方引入 HttpClient 、HttpHeaders 并在構造函數聲明 HttpClient import {HttpClient,HttpHeaders} from "@angular/common/http"; constructor(private http:HttpClient) { } // 實例化// post 提交數據 const httpOptions = {headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; var api = "http://127.0.0.1:4200/doLogin"; this.http.post(api,{username:'瑞萌萌',age:'22'},httpOptions).subscribe(response => {console.log(response); });

    Jsonp請求數據

    // 在 app.module.ts 中引入 HttpClientModule、HttpClientJsonpModule 并注入 import {HttpClientModule,HttpClientJsonpModule} from'@angular/common/http'; imports: [BrowserModule,HttpClientModule,HttpClientJsonpModule ]// 在用到的地方引入 HttpClient 并在構造函數聲明 import {HttpClient} from "@angular/common/http"; constructor(private http:HttpClient) { } // 實例化// jsonp 請求數據 var api = "http://baidu.com/api/productlist"; this.http.jsonp(api,'callback').subscribe(response => {console.log(response); });

    攔截器

    Angular 攔截器是 Angular 應用中全局捕獲和修改 HTTP 請求和響應的方式,例如攜帶 Token 和捕獲 Error

    前提是只能攔截使用 HttpClientModule 發出的請求,如果使用 axios 則攔截不到

    創建攔截器

    // 使用命令 ng g interceptor name,在這里創建攔截器 ng g interceptor LanJieQi // cli 生成攔截器是沒有簡寫方式的import { Injectable } from '@angular/core'; import {HttpRequest,HttpHandler,HttpEvent,HttpInterceptor } from '@angular/common/http'; import { Observable } from 'rxjs';@Injectable() export class LanJieQiInterceptor implements HttpInterceptor {constructor() {}// 默認的 intercept() 方法只是單純的將請求轉發給下一個攔截器(如果有),并最終返回 HTTP 響應體的 Observable// request: HttpRequest<unknown> 表示請求對象,包含了請求相關的所有信息,unknown指定請求體body的類型// next: HttpHandler 請求對象修改完成,將修改后的請求對象通過next中的handle方法傳回真正發送請求的方法中intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {// next 對象表示攔截器鏈表中的下一個攔截器(在應用中可以設置多個攔截器)return next.handle(request);} }

    注入攔截器

    // 在 @NgModule 模塊中注入攔截器 // 攔截器也是一個由 Angular 依賴注入 (DI) 系統管理的服務,也必須先提供這個攔截器類,才能使用它 // 由于攔截器是 HttpClient 服務的依賴,所以必須在提供 HttpClient 的同一個(或其各級父注入器)注入器中提供這些攔截器 @NgModule({imports: [HttpClientModule// others...],providers: [{provide: HTTP_INTERCEPTORS,useClass: LanJieQiInterceptor,// multi: true 表明 HTTP_INTERCEPTORS 是一個多重提供者的令牌,表示這個令牌可以注入多個攔截器multi: true},],bootstrap: [AppComponent] })export class AppModule { }

    請求頭攔截

    @Injectable() export class LanJieQiInterceptor implements HttpInterceptor {constructor() {}intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {// 為了統一設置請求頭,需要修改請求// 但 HttpRequest 和 HttpResponse 實例的屬性卻是只讀(readonly)的// 所以修改前需要先 clone 一份,修改這個克隆體后再把它傳給 next.handle()let req = request.clone({setHeaders:{token:"123456" // 在請求頭中增加 token:123456}// setHeaders 和 headers: request.headers.set('token', '123456') 一致})return next.handle(req)// 將修改后的請求返回給應用} }

    響應捕獲

    @Injectable() export class LanJieQiInterceptor implements HttpInterceptor {constructor() {}intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {let req = request.clone({setHeaders:{token:"123456" // 在請求頭中增加 token:123456}})return next.handle(req).pipe(retry(2), // RxJS的重試操作符 retry 發現異常后自動再請求2次catchError((error:HttpErrorResponse) => throwError(error)))} }

    如果有多個攔截器,請求順序是按照配置順序執行,響應攔截則是相反的順序

    如果提供攔截器的順序是先 A再 B再 C,那么請求階段的執行順序就是 A->B->C,而響應階段的執行順序則是 C->B->A


    Angular表單

    模版驅動表單

    模板驅動表單在往應用中添加簡單的表單時非常有用,但是不像響應式表單那么容易擴展

    如果有非常基本的表單需求和簡單到能用模板管理的邏輯,就使用模板驅動表單

    響應式表單和模板驅動表單共享了一些底層構造塊:

    FormControl 實例用于追蹤單個表單控件的值和驗證狀態

    FormGroup 用于追蹤一個表單控件組的值和狀態

    FormArray 用于追蹤表單控件數組的值和狀態,有長度屬性,通常用來代表一個可以增長的字段集合

    ControlValueAccessor 用于在 Angular 的 FormControl 實例和原生 DOM 元素之間創建一個橋梁

    FormControl 和 FormGroup 是 angular 中兩個最基本的表單對象

    FormControl 代表單一的輸入字段,它是 Angular 表單中最小單員,它封裝了這些字段的值和狀態,比如是否有效、是否臟(被修改過)或是否有錯誤等

    FormGroup 可以為一組 FormControl 提供總包接口(wrapper interface),來管理多個 FormControl

    當我們試圖從 FormGroup 中獲取 value 時,會收到一個 “鍵值對” 結構的對象

    它能讓我們從表單中一次性獲取全部的值而無需逐一遍歷 FormControl,使用起來相當順手

    FormGroup 和 FormControl 都繼承自同一個祖先 AbstractControltractControl(這是 FormControl,FormGroup 和 FormArray 的基類)

    首先加載 FormsModule

    // 先在 NgModule 中導入了 FormsModule 表單庫 // FormsModule 為我們提供了一些模板驅動的指令,例如:ngModel、NgForm import { FormsModule } from '@angular/forms'; @NgModule({ declarations: [ FormsDemoApp, DemoFormSku, // ... our declarations here ], imports: [ BrowserModule, FormsModule,], bootstrap: [ FormsDemoApp ] }) class FormsDemoAppModule {}

    接下來創建一個模版表單

    <div><h2>基礎表單:商品名稱</h2><form #f="ngForm" (ngSubmit)="onSubmit(f.value)"><div class="sku"><label for="skuInput">商品名稱:</label><inputtype="text"id="skuInput"placeholder="商品名稱"name="sku" //使用form時必須定義,可以理解為當前控件的名字ngModel/></div><button>提交</button></form></div>

    我們導入了 FormsModule,因此可以在視圖中使用 NgForm 了

    當這些指令在視圖中可用時,它就會被附加到任何能匹配其 selector 的節點上

    NgForm 做了一件便利但隱晦的工作:它的選擇器包含 form 標簽(而不用顯式添加 ngForm 屬性)

    這意味著當導入 FormsModule 時候,NgForm 就會被自動附加到視圖中所有的標簽上

    NgForm 提供了兩個重要的功能:

    • 一個 ngForm 的 FormGroup 對象
    • 一個輸出事件 (ngSubmit)
    <form #f="ngForm" (ngSubmit)="onSubmit(f.value)" ><!-- 這里使用了 #f=“ngForm”,#v=thing 的意思是我們希望在當前視圖中創建一個局部變量這里為視圖中的 ngForm 創建了一個別名,并綁定到變量 #f這個 ngForm 是由 NgForm 指令導出的ngForm 的類型的對象是 FormGroup 類型的這意味著可以在視圖中把變量 f 當作 FormGroup 使用,而這也正是我們在輸出事件 (ngSubmit) 中的使用方法在表單中綁定 ngSubmit 事件 (ngSubmit)=“onSubmit (f.value)“(ngSubmit) 來自 NgForm 指令onSubmit() 將會在組件類中進行定義f 就是 FormGroup ,而 .value 會以鍵值對的形式返回 FormGroup 中所有控件的值總結:當提交表單時,將會以該表單的值作為參數,調用組件實例上的 `onSubmit` 方法 -->

    NgModel 會創建一個新的 FormControl 對象,把它自動添加到父 FormGroup 上(這里也就是 form 表單對象)

    并把這個 FormControl 對象綁定到一個 DOM 上

    也就是說,它會在視圖中的 input 標簽和 FormControl 對象之間建立關聯

    這種關聯是通過 name 屬性建立的,在本例中是 "name"

    響應式表單

    使用 ngForm 構建 FormControl 和 FormGroup 很方便,但是無法提供定制化選項,因此引入響應式表單

    響應式表單提供了一種模型驅動的方式來處理表單輸入,其中的值會隨時間而變化

    使用響應式表單時,通過編寫 TypeScript 代碼而不是 HTML 代碼來創建一個底層的數據模型

    在這個模型定義好以后,使用一些特定的指令將模板上的 HTML 元素與底層的數據模型連接在一起

    FormBuilder 是一個名副其實的表單構建助手(可以把他看作一個 “工廠” 對象)

    在先前的例子中添加一個 FormBuilder,然后在組件定義類中使用 FormGroup

    // 先在 NgModule 中導入了 ReactiveFormsModule 表單庫 import { ReactiveFormsModule } from '@angular/forms'; @NgModule({imports: [FormsModule,ReactiveFormsModule] }) // 使用 formGroup 和 formControl 指令來構建這個組件,需要導入相應的類 import { FormBuilder, FormGroup,ReactiveFormsModule } from '@angular/forms'; // 在組件類上注入一個從 FormBuilder 類創建的對象實例,并把它賦值給 fb 變量(來自構造函數) export class DemoFormSkuBuilder { myForm: FormGroup; // myForm 是 FormGroup 類型constructor(fb: FormBuilder) { // FormBuilder 中的 group 方法用于創建一個新的 FormGroup// group 方法的參數是代表組內各個 FormControl 的鍵值對this.myForm = fb.group({ // 調用 fb.group () 來創建 FormGroup// 設置一個名為 sku 的控件,控件的默認值為 "123456"'sku': ['123456'] }); }onSubmit(value: string): void { console.log('submit value:', value); } }

    在視圖表單中使用自定義的 FormGroup

    <h2 class="ui header">Demo Form: Sku with Builder</h2> <!-- 當導入 FormsModule 時,ngForm 就會自動創建它自己的 FormGroup但這里不希望使用外部的 FormGroup,而是使用 FormBuilder 創建這個 myForm 實例變量Angular提供了 formGroup 指令,能讓我們使用現有的 FormGroupNgForm 不會應用到帶 formGroup 屬性的節點上這里我們告訴Angular,想用 myForm 作為這個表單的 FormGroup --> <form [formGroup]="myForm" <label for="skuInput"> SKU </label> <input type="text" id="skuInput" placeholder="SKU" [formControl]="myForm.controls['sku']"> <!-- 將 FormControl 綁定到 input 標簽上 : ngModel 會創建一個新的 FormControl 對象并附加到父 FormGroup 中但在例子中,我們已經用 FormBuilder 創建了自己的 FormControl要將現有的 FormControl 綁定到 input 上,可以用 formControl 指令將 input 標簽上的 formControl 指令指向 myForm.controls 上現有的 FormControl 控件 sku -->

    記住以下兩點:

  • 如果想隱式創建新的 FormGroup 和 FormControl,使用:ngForm、ngModel
  • 如果要綁定一個現有的 FormGroup 和 FormControl,使用:formGroup、formControl
  • 表單驗證

    用戶輸入的數據格式并不總是正確的,如果有人輸入錯誤的數據格式,我們希望給他反饋并阻止他提交表單

    因此,我們要用到驗證器,由 validators 模塊提供

    Validators.required 是最簡單的驗證,表明指定的字段是必填項,否則就認為 FormControl 是無效的

    如果 FormGroup 中有一個 FormControl 是無效的, 那整個 FormGroup 都是無效的

    要為 FormControl 對象分配一個驗證器 ,可以直接把它作為第二個參數傳給 FormControl 的構造函數

    const control = new FormControl('name', Validators.required);// 在組件定義類中使用 FormBuilderconstructor(fb: FormBuilder) { this.myForm = fb.group({ 'name': ['',Validators.required] }); this.name = this.myForm.controls['name']; }

    在視圖中檢查驗證器的狀態,并據此采取行動

    template:`<div><h2>商品表單:商品名稱</h2><form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm)"><div><label for="nameInput">商品名稱:</label><inputtype="text"id="nameInput"placeholder="請輸入名稱"[formControl]="myForm.controls['name']"/><div style="color:red" *ngIf="!name.valid">名稱無效</div><div style="color:red" *ngIf="name.hasError('textinvalid')">名稱不是以“123”開頭</div><div *ngIf="name.dirty">數據已變動</div></div><div><label for="codeInput">商品料號:</label><inputtype="text"id="codeInput"placeholder="請輸入料號"[formControl]="myForm.controls['code']"/><divstyle="color:red"*ngIf="myForm.controls.code.hasError('required')">該項必填</div><divstyle="color:red"*ngIf="myForm.controls.code.hasError('pattern')">只可輸入數字和英文</div></div><div style="color:green" *ngIf="myForm.isvalid">表單無效</div><div style="color:green" *ngIf="myForm.valid">表單有效</div><button type="submit">提交</button></form></div>` export class NonInWarehouseComponent implements OnInit {myForm: FormGroup;name: AbstractControl;constructor(fb: FormBuilder) {this.myForm = fb.group({name: ['牛奶', Validators.compose([Validators.required, textValidator])],code: ['', [Validators.required, Validators.pattern('^[A-Za-z0-9]*$')]],});this.name = this.myForm.controls.name;}ngOnInit() {const nameControl = new FormControl('nate');console.log('nameControl', nameControl);}onSubmit(a: any) {console.log('a', a);} }

    內置校驗器

    Angular 提供了幾個內置校驗器,下面是比較常用的校驗器:

    • Validators.required - 表單控件值非空
    • Validators.email - 表單控件值的格式是 email
    • Validators.minLength() - 表單控件值的最小長度
    • Validators.maxLength() - 表單控件值的最大長度
    • Validators.pattern() - 表單控件的值需匹配 pattern 對應的模式(正則表達式)

    自定義驗證器

    假設我們的 name 有特殊的驗證需求,比如 name 必須以 123 作為開始

    當輸入值(控件的值 control.value)不是以 123 作為開始時,驗證器會返回錯誤代碼 invalidSku

    // angular 源代碼中實現 Validators.required export class Validators {// 接收一個 AbstractControl 對象作為輸入static required(control: AbstractControl): ValidationErrors | null; } // 當驗證器失敗時,會返回一個 String Map<string,any> 對象,他的鍵是” 錯誤代碼 “,它的值是 true export declare type ValidationErrors = {[key: string]: any; };// 自定義驗證器 function textValidator(controls: FormControl // 因為FormControl繼承于 AbstractControl 所以也可以寫成FormControl對象 ): {[s: string]: boolean; } {if (!controls.value.match(/^123/)) {return { textinvalid: true };} }

    給 FormControl 分配驗證器,但是 name 已經有一個驗證器了,如何在同一個字段上添加多個驗證器

    用 Validators.compose 來實現

    Validators.compose 把兩個驗證器包裝在一起,我們可以將其賦值給 FormControl

    只有當兩個驗證器都合法時,FormControl 才是合法的

    Validators.compose([Validators.required, textValidator]) // 不用compose [Validators.required, textValidator] // 保留 compose 是為了向以前歷史版本進行兼容,不用 compose 也可實現

    動態表單

    要實現 Angular 動態表單,主要使用 formArray 方法,formArray 生成的實例是一個數組,在這個數組中可以動態的放入 formGroup 和 formControl,這樣便形成了動態表單。

    export class ReativeFormsComponent implements OnInit {ngOnInit() {this.addContact()}//動態表單personMess: FormGroup = new FormGroup({//生成動態表單數組contacts: new FormArray([]) })//獲取數組對象get contacts(){return this.personMess.get('contacts') as FormArray}//增加一個表單組addContact(){let myContact = new FormGroup({name: new FormControl(),phone: new FormControl()})this.contacts.push(myContact)}//刪除一個表單組deleteContact(i:number){this.contacts.removeAt(i)}//提交表單OnSubmit() {console.log(this.personMess.value)} } <form [formGroup]="personMess" (submit)="OnSubmit()"><div formArrayName="contacts"><!-- 注意:這里遍歷的時contacts.controls --><div *ngFor="let contact of contacts.controls;let i =index" [formGroupName]="i"><input type="text" formControlName="name"><input type="text" formControlName="phone"><button (click)="deleteContact(i)">刪除信息</button></div></div><button (click)="addContact()">添加信息</button><br><input type="submit"> </form>

    Angular CDK

    CDK 是 Component Dev kit 的簡稱,是 Angular Material 團隊在開發 Library 時發現組件有很多相似的地方,最后進行了抽取,提煉出了公共的邏輯,這部分即是 CDK

    官方用了一個很形象的比喻:如果組件庫是火箭飛船,那么 CDK 就是發動機零件盒

    總結

    以上是生活随笔為你收集整理的也许是全网最全的 Angular 新手入门指南的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    国产伦精品一区二区三区… | 久久99精品国产99久久6尤 | 国产一区福利 | 天天超碰 | 色婷婷视频在线观看 | 国产精品a久久久久 | 手机看国产毛片 | 在线日韩一区 | 亚洲综合在线五月天 | 亚洲欧美成aⅴ人在线观看 四虎在线观看 | 91av官网| 国产网红在线观看 | 久久99深爱久久99精品 | av片子在线观看 | 五月天婷婷在线观看视频 | 在线免费观看黄网站 | 国产喷水在线 | 中文字幕欧美日韩va免费视频 | 成人91在线 | 午夜18视频在线观看 | 欧美性大胆 | 亚洲成a人片77777kkkk1在线观看 | av片在线看 | 日韩试看| 国产在线观看a | 国产区 在线 | 中文字幕国语官网在线视频 | 成人网在线免费视频 | 九九久久精品 | 91精品国产自产老师啪 | 免费视频黄 | 天天射天天操天天色 | www91在线| 在线观看91精品国产网站 | 欧美国产精品一区二区 | 97超碰国产在线 | 久久免费视频7 | 麻豆一区二区 | 久草在线久草在线2 | 2021国产精品视频 | 欧美日韩一区二区在线观看 | 一级久久精品 | 国产中文字幕久久 | 国产黄色理论片 | 99色国产 | 久久热亚洲 | 亚洲片在线观看 | 日日干 天天干 | 国产精品99久久久 | 99视频在线免费看 | 日韩免费观看视频 | 成人一级视频在线观看 | 婷婷久久精品 | 久 久久影院 | 亚洲欧美日韩一二三区 | 久久与婷婷 | 91香蕉视频在线 | 婷婷六月综合网 | 精品国产一二区 | 免费观看www7722午夜电影 | 国产一区 在线播放 | 国产午夜精品久久久久久久久久 | 亚洲国产中文字幕在线观看 | 一级性生活片 | 日韩欧美国产精品 | 久久免费在线视频 | 色综合婷婷 | 全久久久久久久久久久电影 | 国产一区免费视频 | 97国产一区二区 | 国产色就色 | 四川妇女搡bbbb搡bbbb搡 | 亚洲精品系列 | 国产日产精品一区二区三区四区的观看方式 | 日本免费久久高清视频 | 激情五月婷婷激情 | 久久综合狠狠综合久久综合88 | 国产专区日韩专区 | 网址你懂的在线观看 | 2024国产精品视频 | 国产精品麻豆欧美日韩ww | 99精品国产在热久久 | 国产伦精品一区二区三区照片91 | 操少妇视频 | 久久高清免费观看 | 在线视频 影院 | 在线免费观看黄色 | 免费看污黄网站 | 在线精品视频在线观看高清 | 男女全黄一级一级高潮免费看 | 久久人人爽人人爽人人片av免费 | 青青河边草免费直播 | av中文字幕网站 | 日韩在线电影观看 | 看全黄大色黄大片 | 午夜.dj高清免费观看视频 | 日韩中文字幕在线看 | 欧美在线1 | 久久国产网| 亚洲最大在线视频 | 99热手机在线 | 国产最新视频在线 | 中国一级片在线播放 | 欧美日韩精品在线观看视频 | 99在线观看 | 天天射射天天 | 婷婷综合影院 | 久久综合九色综合久99 | 九九在线免费视频 | 中文字幕在线国产 | 午夜婷婷网 | 人人玩人人添人人 | 97视频在线观看成人 | 一区二区三区在线免费播放 | 又大又硬又黄又爽视频在线观看 | 国产中文字幕一区 | 亚洲狠狠婷婷 | 国产免费成人 | 久久国产精品99国产 | 午夜国产福利在线观看 | 一区二区三区在线视频观看58 | 伊人欧美 | 欧美日韩精品在线播放 | 国产精品免费在线观看视频 | 久久婷婷精品 | 91精品国产91 | 亚洲激情在线 | 麻豆国产网站入口 | 99精品视频播放 | 91免费试看| 色片网站在线观看 | 99在线视频精品 | 婷婷激情五月 | 精品免费在线视频 | 国产精品成人av电影 | 婷婷丁香色综合狠狠色 | 在线观看国产区 | 又黄又网站 | 最新av免费在线 | 国产精品大尺度 | 麻豆视频在线观看免费 | 蜜桃视频色 | 成人av日韩 | 中文字幕在线播放日韩 | av看片在线观看 | 手机av看片 | 欧美亚洲一区二区在线 | 成人99免费视频 | av国产在线观看 | 久久人人爽人人人人片 | 国产精品一区二区久久国产 | 久草免费资源 | 天天搞天天干 | 成人性生交大片免费看中文网站 | 91视频在线自拍 | 久久精品系列 | 日本精品一区二区三区在线观看 | 国产精品手机在线播放 | 日韩高清av在线 | 99久久精品国产亚洲 | 亚洲va欧洲va国产va不卡 | 超碰电影在线观看 | 在线黄色免费av | 91成人精品一区在线播放69 | 免费日韩一区 | 亚洲干视频在线观看 | 不卡中文字幕av | 国产精品一区二区久久精品爱涩 | 韩日电影在线观看 | 人交video另类hd | 69av在线播放 | 亚洲不卡av一区二区三区 | 99免费看片 | 国产欧美在线一区 | 天天射天天干天天爽 | 最近日本字幕mv免费观看在线 | 超碰99在线 | 97av影院| 91精品国产一区二区三区 | 久久久久久久久久亚洲精品 | 日韩在线大片 | 91福利在线观看 | 免费观看的av网站 | 亚洲国产精品激情在线观看 | 亚洲小视频在线观看 | 国产99久久久精品 | 国产精品婷婷午夜在线观看 | 天天爱天天操天天射 | 成人91在线观看 | 亚洲成人av电影在线 | 91精品免费在线 | 操操操日日日干干干 | 中文成人字幕 | 日韩高清不卡一区二区三区 | 日韩电影一区二区三区 | 国产精品中文久久久久久久 | 日韩av进入 | 成年人免费观看在线视频 | 日韩xxxxxxxxx | 亚洲视频大全 | 日本最新高清不卡中文字幕 | 欧美做受高潮 | 人人插人人射 | www.五月婷 | 麻豆国产网站 | 国产高清久久 | 黄色大片免费播放 | 97视频免费看 | 欧美激情精品久久久久久变态 | 国产伦精品一区二区三区四区视频 | 久久久久美女 | 日韩电影在线一区 | 欧美aaaxxxx做受视频 | 国产精品视频久久久 | 综合精品久久久 | 国产在线综合视频 | 亚洲精品国产综合99久久夜夜嗨 | 国产少妇在线观看 | 九九免费视频 | 国产激情小视频在线观看 | 少妇搡bbbb搡bbb搡忠贞 | 午夜影视剧场 | 久久久受www免费人成 | 国产黄色免费在线观看 | 国产99久久久国产 | 欧美日韩亚洲精品在线 | 一级片免费观看视频 | 国产高清免费在线播放 | 日日干夜夜草 | 在线观看国产区 | 99九九热只有国产精品 | 97超碰伊人| 久草在线看片 | 天天av天天 | 日韩av电影网站在线观看 | 97夜夜澡人人爽人人免费 | 精品久久久国产 | 日韩久久久久久久久久久久 | 日韩视频免费播放 | 亚洲dvd| 成人资源在线观看 | 一本大道久久精品懂色aⅴ 五月婷社区 | av网站大全免费 | 国产精彩在线视频 | 日韩区欠美精品av视频 | 97狠狠干 | 又紧又大又爽精品一区二区 | 欧美成人精品三级在线观看播放 | 国产精品久久久久免费 | 国内精品久久久久久久久久久 | av一级片| 日女人电影 | 在线免费观看黄网站 | 一级黄色片在线播放 | 中文字幕免费高 | 91九色成人 | 婷婷色综合| 97在线超碰 | 一区二区高清在线 | 午夜精品久久一牛影视 | a黄色大片 | 丁香午夜 | 国产精品123 | 国产亚洲精品久久19p | 亚洲永久精品在线 | 国产精品九九久久99视频 | 日韩综合视频在线观看 | 久久久久久久国产精品视频 | 丁香综合网 | 久久手机免费观看 | 在线观看黄av | 一区二区三区四区五区在线视频 | 中文字幕精品一区久久久久 | 美女露久久 | 成人国产一区二区 | 午夜久久精品 | 曰韩精品| 在线观看亚洲成人 | 免费在线观看不卡av | 夜色资源网 | 久草在线视频在线观看 | 黄色avwww| 一本一本久久a久久精品综合 | 国产一区二区高清视频 | 国产成人精品三级 | 日日夜夜干 | 国产精品99久久久久 | 色偷偷人人澡久久超碰69 | 精品a级片 | 日韩在线电影一区 | 探花视频在线版播放免费观看 | 欧美日韩视频在线一区 | 天天射天天干天天爽 | 爱情影院aqdy鲁丝片二区 | 91久久偷偷做嫩草影院 | 久久免费视频1 | 在线观看国产永久免费视频 | 色先锋av资源中文字幕 | 国产麻豆电影在线观看 | 亚洲精品毛片一级91精品 | www免费在线观看 | 激情综合五月婷婷 | 久久艹欧美 | 国产精品男女啪啪 | 国产在线播放观看 | 亚洲精品在线观看免费 | 精品视频专区 | 久久人人爽人人爽人人片 | 国产成人精品午夜在线播放 | 久久亚洲电影 | 99久久婷婷国产综合亚洲 | 国产91精品高清一区二区三区 | 国产最新福利 | 婷婷日韩| 国产视频2区 | 国产亚洲精品久久久久久久久久久久 | 日韩av三区| 九九免费视频 | 六月天综合网 | 日韩在线不卡视频 | 特级aaa毛片| 成人av免费网站 | 香蕉在线观看视频 | 亚洲在线不卡 | 在线影视 一区 二区 三区 | 黄色小说网站在线 | 久久99亚洲精品 | 久久综合婷婷国产二区高清 | www.福利视频 | 欧美在一区 | 久久久2o19精品 | 四虎在线免费视频 | 日韩av不卡在线播放 | 久久人人爽人人人人片 | 色av资源网 | 人人爱人人射 | 久久国产精品99久久久久久进口 | 91在线播| 国产在线播放一区二区三区 | 国产精品aⅴ | 美女视频久久黄 | 国产尤物一区二区三区 | 亚洲色视频 | 日韩av一卡二卡三卡 | 女人高潮一级片 | 日本在线中文在线 | 天天操综合 | 伊甸园永久入口www 99热 精品在线 | 国产精品欧美久久久久天天影视 | 丝袜美腿在线播放 | 日韩在线高清视频 | 精品产品国产在线不卡 | 日韩av一区二区三区在线观看 | 91亚洲精品久久久蜜桃借种 | 最新日韩电影 | 五月天婷婷免费视频 | 99精品欧美一区二区三区 | 色在线观看网站 | 亚洲综合色丁香婷婷六月图片 | 久久精品一 | 最新日本中文字幕 | 丁香婷婷激情国产高清秒播 | av电影中文字幕在线观看 | 成人网444ppp| 在线观看亚洲国产精品 | 99色在线视频 | 国产亚洲精品久久久久久大师 | 最新超碰在线 | 欧美精品国产综合久久 | 特黄色大片 | 欧美一区二区三区在线 | 中文字幕在线看视频国产中文版 | 美女黄濒 | 在线一区av | 在线小视频你懂得 | 一色av| 国产成人精品日本亚洲999 | 精品久久视频 | 国产精品24小时在线观看 | 激情av综合 | 国产精品va在线播放 | 亚洲无在线 | 亚洲少妇影院 | av九九| 国产精品网红福利 | 97人人人| 久久久影视 | 亚洲黄色免费电影 | 就要干b | 天天操天天拍 | 久久久久久久久久久综合 | 成人精品国产 | 亚洲国产经典视频 | 久久99亚洲精品久久 | 五月激情综合婷婷 | 91网免费观看| 日本久热 | 天海冀一区二区三区 | 天天做天天爱天天综合网 | 亚洲一区二区三区91 | 国产成人综合在线观看 | 久亚洲 | 久久免费在线 | 精品中文字幕在线播放 | 精品国偷自产国产一区 | 欧美一区,二区 | 视频在线日韩 | 日日夜日日干 | 久草免费在线观看视频 | 国产一级做a爱片久久毛片a | 操处女逼 | 国产一区二区精品久久 | 91福利国产在线观看 | se视频网址| 国产精品99精品久久免费 | 在线观看网站你懂的 | 国产成人精品亚洲精品 | 夜夜干天天操 | 天堂在线一区 | 在线免费观看黄色大片 | 亚洲精品动漫久久久久 | 操操操com| 免费无遮挡动漫网站 | 天海冀一区二区三区 | 精品久久久久国产 | 日韩网站视频 | 日韩精品久久久久久久电影竹菊 | 在线观看的av网站 | 五月天综合色 | 天天操欧美 | 中文字幕日韩电影 | 四虎影视精品成人 | 精品一区二区免费 | 国产视频欧美视频 | 国产精品久久精品 | 国产午夜精品理论片在线 | 中文字幕在线观看第一区 | 成人在线免费视频 | 在线视频app | 成年人免费在线观看网站 | 天天射射天天 | 又黄又爽免费视频 | 成片视频在线观看 | 欧美9999| 亚洲精品美女在线观看播放 | 人人操日日干 | 亚洲综合最新在线 | 国产亚洲视频在线免费观看 | 久久中文字幕视频 | 欧美另类交在线观看 | 五月色综合 | 国产精品一区二区电影 | 亚洲欧洲精品久久 | 欧美日韩aaaa | av免费看网站 | 亚洲国产欧美一区二区三区丁香婷 | 午夜性盈盈 | 中文字幕在线播放视频 | 久久看免费视频 | 999久久a精品合区久久久 | 最新日韩中文字幕 | 最近日本韩国中文字幕 | 欧美va天堂va视频va在线 | 久在线观看视频 | 六月丁香社区 | 狠狠色丁香婷婷综合视频 | 精品超碰 | 超碰com | 在线视频麻豆 | 久久网站av| 99精品黄色片免费大全 | 国产成人精品午夜在线播放 | 久久精品a | 91热爆视频 | 日韩在线电影一区 | 欧美日韩亚洲第一页 | 国产久视频 | 亚洲日本va中文字幕 | 91视频三区| 成年人免费电影 | 五月婷婷在线播放 | 五月婷婷久久丁香 | 91成人看片 | 国产精品1区2区在线观看 | 日韩欧美视频一区二区三区 | 制服丝袜在线 | 免费在线观看国产黄 | 天天操,夜夜操 | 成人av视屏 | 国产亚洲精品久久久久久移动网络 | 日韩精品在线播放 | 久草视频在线观 | 久久看片网站 | 免费成人结看片 | 亚洲女在线 | 人人干人人干人人干 | 一本到视频在线观看 | 在线免费黄色av | 国产在线免费观看 | 免费看黄色毛片 | 黄色日本片| 天天干天天插伊人网 | 久久免费av电影 | 亚洲精品午夜久久久久久久久久久 | 免费看片网址 | 国产视频丨精品|在线观看 国产精品久久久久久久久久久久午夜 | 久久亚洲欧美日韩精品专区 | 8x成人免费视频 | 日韩高清免费无专码区 | 精品国产成人在线 | 午夜一级免费电影 | 日韩av午夜在线观看 | 天天射天| 97色噜噜 | 2021国产在线 | 成人小视频在线播放 | 久久精品99国产精品 | 久久人人爽人人 | 精品久久福利 | 国产一级视频在线观看 | 蜜臀aⅴ国产精品久久久国产 | 91麻豆.com | 91在线看视频免费 | 天天干,天天射,天天操,天天摸 | 久热这里有精品 | 99re8这里有精品热视频免费 | 欧美污在线观看 | 欧美激精品 | 免费在线观看污网站 | 国产 欧美 在线 | 91av网址| 精品女同一区二区三区在线观看 | 久久久精品高清 | 日韩av电影免费在线观看 | 不卡的一区二区三区 | 性色av香蕉一区二区 | 成年人视频在线免费观看 | 日本婷婷色 | 久热电影| 天天躁日日躁狠狠 | 欧美老人xxxx18 | 久久精彩视频 | www.五月天婷婷 | 在线看v片成人 | 91麻豆精品国产91久久久使用方法 | 国产成人精品综合 | 国产一区二区三区四区在线 | 精品国产诱惑 | 国内免费久久久久久久久久久 | 天天摸夜夜添 | 久久综合9988久久爱 | 亚洲国产精品99久久久久久久久 | 久久免费成人精品视频 | 日本中文字幕在线播放 | 国产91精品久久久久 | 亚洲艳情 | 久久国产乱| 国产午夜精品视频 | 91av社区 | 特级毛片爽www免费版 | 国产h在线观看 | www.亚洲黄 | 香蕉国产91 | 97热在线观看 | 国产在线精品一区二区 | 99爱爱 | 日韩av视屏 | 婷婷国产在线 | 狠狠操狠狠 | 日韩一区二区三区免费视频 | 国产不卡一二三区 | a视频免费看 | 中文 一区二区 | 欧美日韩精品久久久 | 激情视频二区 | 亚洲国产中文在线 | 午夜精品一区二区三区视频免费看 | 在线视频一二区 | 欧美一级性生活视频 | 奇米影视777四色米奇影院 | 在线免费观看国产黄色 | 九九导航 | 天天综合天天做天天综合 | www免费黄色| 国产短视频在线播放 | 一级黄色毛片 | 久久9精品| 免费观看一级视频 | 日韩欧美在线播放 | 久草免费新视频 | 久久免费播放 | 亚洲精品高清视频在线观看 | 久久你懂的 | 免费精品在线观看 | 福利视频入口 | 91精品亚洲影视在线观看 | 精品一区在线 | 亚洲人成影院在线 | 欧美一区二区在线 | 国产中年夫妇高潮精品视频 | 久久99久国产精品黄毛片入口 | 99人久久精品视频最新地址 | 美女视频网站久久 | 中文字幕黄色网 | 人人干,人人爽 | 天天插日日插 | 国产精品久久久久久电影 | 午夜av激情| www日韩在线 | av大片免费看 | 久久久免费 | 亚洲综合五月 | 亚洲人在线视频 | 国产日韩视频在线播放 | 中文字幕在线视频精品 | 日韩欧美一区二区三区在线观看 | 欧美日韩视频在线播放 | 久久与婷婷 | 综合在线观看 | 五月婷婷综 | 在线观看黄色 | 99久在线精品99re8热视频 | 亚洲狠狠丁香婷婷综合久久久 | 日韩免费在线看 | 免费在线观看国产黄 | 在线观看视频国产一区 | 国产午夜精品视频 | 中文字幕一区二区三区在线视频 | 中文字幕在线观看三区 | 最新av免费| 亚州精品在线视频 | 欧美动漫一区二区三区 | 在线看中文字幕 | 欧美精品免费一区二区 | 亚洲视频资源在线 | 99热这里只有精品国产首页 | 日本乱视频 | 日韩欧美视频免费观看 | 99久久精品久久亚洲精品 | 国产精品免费大片视频 | 亚洲一级片av | 欧美乱大交 | 国内精品视频免费 | 97av影院| 久久久久一区二区三区四区 | 午夜av在线免费 | 亚洲精品综合欧美二区变态 | 91成人免费看片 | 久草视频首页 | 久久精精品视频 | 久久精品综合视频 | 国产成人免费网站 | 亚洲精品视频在线观看网站 | 国产伦精品一区二区三区在线 | 亚洲经典中文字幕 | 国产经典三级 | 国产一级特黄电影 | 欧美一区日韩一区 | 国产精品欧美激情在线观看 | 国产精品久久久久高潮 | 91成人黄色 | 91久久久久久久一区二区 | 狠狠干狠狠插 | 久操视频在线观看 | 在线视频一区观看 | 一级黄色大片 | 久久久国产一区二区三区 | 人人爽人人爽人人片av | 国产精久久久 | 国产精品久久久久久久久久免费看 | 狠狠干狠狠插 | 免费涩涩网站 | 香蕉国产91 | 婷婷国产精品 | 久久精品高清视频 | 九九视频在线播放 | 久久精品一二区 | 日韩免费在线视频观看 | 日韩国产精品久久 | 五月天久久综合网 | 午夜精品一区二区三区免费 | 久久久久久久久久久久亚洲 | 国产在线欧美在线 | 在线午夜| japanesexxxhd奶水 91在线精品一区二区 | 国产在线污 | 精品亚洲午夜久久久久91 | 欧美综合久久久 | 成人免费视频免费观看 | 久久综合狠狠综合 | 91精品办公室少妇高潮对白 | 日韩在线观看免费 | 99精品视频免费看 | 日韩3区| 亚州精品天堂中文字幕 | 成人国产精品久久久 | 婷婷激情站| 激情网在线视频 | 国产午夜一级毛片 | 蜜臀久久99精品久久久无需会员 | 国产不卡在线视频 | 国产精品久久二区 | 一区二区视频欧美 | 亚洲精品乱码久久久久久9色 | 夜色资源站wwwcom| 月下香电影 | www黄色av| 又色又爽又黄 | 天天躁天天躁天天躁婷 | 久草在线免费资源站 | av免费看在线 | 久久免费av电影 | 99999精品 | 97视频免费在线 | 亚洲精品在线播放视频 | 色五丁香 | 视频一区二区国产 | 欧美日韩国产成人 | 中文av网站 | 四虎免费av | 国产精品亚洲a | 91在线日韩 | 手机在线中文字幕 | 国产一区二区久久久 | 98超碰在线| 日日夜夜天天 | 91在线播放国产 | 亚洲精品一区二区三区在线观看 | 在线亚洲播放 | 精品欧美一区二区在线观看 | 一级黄毛片| 久久国产露脸精品国产 | 日本中文字幕在线一区 | 亚洲精品欧洲精品 | 久久久国产影院 | 成人午夜剧场在线观看 | 天堂久久电影网 | 中文av日韩 | 精品久久久久久亚洲综合网站 | 福利视频一区二区 | 国产激情电影综合在线看 | 国产一级黄色片免费看 | 欧美一区二区三区特黄 | 美女免费黄网站 | 久久av网 | 美女视频黄是免费的 | 欧美亚洲国产一卡 | 中文字幕黄色网 | av电影在线免费 | 狠狠干婷婷色 | 射久久久| 91色一区二区三区 | 精品国产一区二区久久 | 久久99国产精品免费网站 | 九色在线视频 | 国产成人99av超碰超爽 | 97精品国产97久久久久久粉红 | 97人人看 | 国产一级片网站 | 免费人成网ww44kk44 | 日韩中文在线字幕 | av免费在线观看网站 | 精品视频专区 | 亚洲精品456在线播放 | 超碰个人在线 | 91精品国产麻豆 | 日韩剧情 | 99色在线 | 九九涩涩av台湾日本热热 | 久久精品国产精品 | 亚洲aⅴ乱码精品成人区 | av不卡在线看 | 伊人官网 | 国产精品免费一区二区三区在线观看 | 国产专区视频在线观看 | 国产精品久久久网站 | 黄网站免费大全入口 | 狠狠色丁香婷婷综合视频 | 看片网站黄色 | 亚洲欧美精品一区 | 在线观看香蕉视频 | 免费进去里的视频 | 日韩精品在线免费播放 | 69av视频在线观看 | 黄色av一区二区三区 | 视频在线91| 久草在线精品观看 | 五月天com| 国产性天天综合网 | 亚洲国产美女精品久久久久∴ | 国产精品九色 | 久久国产精品99久久人人澡 | 久久国产精品成人免费浪潮 | 国产一级片毛片 | 亚洲精品在线视频播放 | 久久蜜臀av | 日韩av一区二区三区四区 | 色偷偷av男人天堂 | 又黄又爽的视频在线观看网站 | 视频一区二区在线 | 少妇bbbb | 丁香在线观看完整电影视频 | 一区二区三区四区五区六区 | 91精品在线麻豆 | 久久精品国产亚洲a | 天天草天天草 | 福利视频入口 | 国内精品小视频 | 日本久久精 | 中文字幕色在线 | 色婷婷九月 | 久久一区国产 | 九色琪琪久久综合网天天 | 精品久久国产精品 | 久久免费黄色大片 | 日韩精品中文字幕在线 | 97超碰在线久草超碰在线观看 | 欧美精品久久久久久久久久久 | 麻豆影视在线播放 | 国产精品福利在线播放 | 久久精品中文字幕少妇 | 日韩网站视频 | 欧美一区二区三区在线看 | 亚洲永久精品在线观看 | 亚洲免费精品视频 | 国产一级不卡毛片 | 黄色特级片 | 日本久久久久久 | 亚洲精品黄 | 国内精品久久影院 | 亚洲高清国产视频 | 亚洲自拍偷拍色图 | 国产我不卡 | 久久久精品一区二区 | 久久福利精品 | 国产精品手机在线 | 六月激情| 国产色一区 | 成人av电影网址 | 国产一在线精品一区在线观看 | 久国产在线播放 | 九九热有精品 | 亚洲成人网在线 | 国产一级电影 | 香蕉看片| 国产成人性色生活片 | 99久久精品免费看 | 国产电影一区二区三区四区 | 在线观看免费一级片 | 日韩免费av片 | 在线观看91久久久久久 | 91av在线视频免费观看 | 91传媒在线 | 日韩免费看片 | 免费一级日韩欧美性大片 | 日韩成人邪恶影片 | 欧美日韩在线免费视频 | 国产在线传媒 | 最近2019中文免费高清视频观看www99 | 91av在线不卡 | 欧美日韩亚洲一 | 夜夜躁狠狠躁日日躁 | 国产午夜小视频 | 日韩精品久久久久久久电影竹菊 | 91精品国产92久久久久 | 免费看一级特黄a大片 | 日韩av免费观看网站 | 国产精品美女久久久久久久网站 | www.香蕉视频| 国产精品九色 | 日本不卡123区 | 一区二区三区四区五区在线视频 | 成人少妇影院yyyy | 精品国产免费av | 伊人春色电影网 | 十八岁以下禁止观看的1000个网站 | 在线看黄色av| 国产精品久久久久久久99 | 中文字幕有码在线观看 | 91精品视屏 | 最新国产一区二区三区 | 日韩免费一级电影 | 狠狠五月天 | 婷婷丁香在线观看 | 久久久综合香蕉尹人综合网 | 国产精品美女 | 九九热精品视频在线播放 | 97电影网手机版 | 在线观看国产永久免费视频 | 91视频亚洲| 激情欧美一区二区三区免费看 | 我要色综合天天 | 日韩欧美专区 | 天堂在线视频中文网 | 91大神精品视频在线观看 | 日韩av高清 | 国产成人精品女人久久久 | 成人a免费视频 | 99中文视频在线 | 天天爱天天射天天干天天 | 精品久久免费 | 91成人网在线 | 人人干在线| 婷婷成人综合 | 久久久久中文 | 激情偷乱人伦小说视频在线观看 | 亚洲国产中文在线观看 | 午夜精品久久久久久久99水蜜桃 | 夜夜高潮夜夜爽国产伦精品 | 日韩精品中文字幕在线播放 | 亚洲国产最新 | 国产精品久久久久久久婷婷 | 黄色毛片视频免费 | 国产三级午夜理伦三级 | 国产福利久久 | 蜜臀91丨九色丨蝌蚪老版 | 精品免费久久 | 亚洲欧美国产精品 | 午夜在线看片 | 国产高清不卡 | 狠狠干美女 | 99在线视频精品 | 国产一区二区在线免费 | 午夜精品久久久 | 日韩美在线观看 | 99久热在线精品视频成人一区 | 久久人人插 | 久久精品这里都是精品 | 国产最新福利 | 婷婷视频 | 狠狠色噜噜狠狠 | 欧美日韩中文国产一区发布 | 欧美一区成人 | 人人插人人草 | 一区二区三区 中文字幕 | 日日色综合 | free. 性欧美.com | 欧美色精品天天在线观看视频 | 一区二区三区免费在线观看视频 | 日日夜夜狠狠 | 一区二区理论片 | 久香蕉 | 又黄又刺激的网站 | 这里有精品在线视频 | 欧美99热 | 国产精品不卡在线观看 | 五月天天av | 亚洲理论视频 | 手机在线看片日韩 | 久久久久99精品国产片 | 成人黄色电影视频 | 国产无限资源在线观看 | 亚洲三级黄色 | 不卡视频一区二区三区 | www.av小说| 国产精品第二页 | www.亚洲精品视频 | 亚洲伊人成综合网 | 丁香六月婷婷综合 | 亚洲成人av一区 | 国产在线p | 久久一久久 | 亚洲激情五月 | 久久影视中文字幕 | 亚洲一区二区精品在线 | 日韩高清在线一区二区 | 91九色成人蝌蚪首页 | 日韩精品在线播放 | 精品国产99 | 91在线产啪 | 一区二区三区四区久久 | 特级西西444www大胆高清无视频 | 欧美日韩国产欧美 | 日韩欧美在线免费观看 | 不卡国产视频 | 精品夜夜嗨av一区二区三区 | 欧美一级片免费观看 | 永久免费的啪啪网站免费观看浪潮 | 日韩成人免费观看 | 中文字幕在线播放日韩 | 国产高清免费视频 | 蜜臀久久99精品久久久久久网站 | 天天爱天天操 | av网站免费看 | 夜添久久精品亚洲国产精品 | 国产日韩高清在线 | 香蕉免费 | 最近中文国产在线视频 | 欧美成年人在线视频 | 国产成人黄色 | 日韩精品视频在线免费观看 | 午夜精品久久久久久久久久久久 | 又爽又黄在线观看 | 亚洲经典视频在线观看 | 96精品在线 | 蜜臀av.com| 久久黄色网址 | 欧美做受高潮 |