Angular7入門總結篇
6<time datetime="2019-01-08T11:34:05.000Z" style="box-sizing: border-box; margin-right: 8px;">2019.01.08 19:34:05</time>字數(shù) 4854閱讀 46093
<article class="_2rhmJa" style="box-sizing: border-box; display: block; font-weight: 400; line-height: 1.8; margin-bottom: 20px; color: rgb(64, 64, 64); font-family: -apple-system, BlinkMacSystemFont, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
發(fā)表于 http://blog.poetries.top/2019/01/09/angular7-intro-summary
最近在學
Ionic4
外盯,不得不學習angular
宋彼、Typescript
基礎知識誊涯,這里簡單總結記錄一下放坏。
一蚤认、Angular 介紹
Angualr
是一款來自谷歌的開源的web
前端框架辛萍,誕生于2009
年儒搭,由Misko Hevery
等 人創(chuàng)建悲柱,后為JS
框架凡涩,已經(jīng)被用于
- 根據(jù)項目數(shù)統(tǒng)計
angular(1.x 疹蛉、2.x 活箕、4.x、5.x可款、6.x育韩、7.x)
是現(xiàn)在網(wǎng)上使用量最大的框架 -
Angualr
基于TypeScript
和react
、vue
相比,Angular
更適合中大型企業(yè)級項目闺鲸。
目前 2018 年 11 月 25 日
angular
最新版本angular7.x
筋讨。根據(jù)官方介紹,Angular
每過幾個月 就會更新一個版本摸恍。此教程同樣適用于后期更新的Angular8.x
悉罕、Angular9.x
學習 Angular 必備基礎
必備基礎:
html
、css
立镶、js
壁袄、es6
、Typescript
二媚媒、Angular 環(huán)境搭建及創(chuàng)建項目
2.1 環(huán)境搭建
1. 安裝 nodejs
安裝
angular
的計算機上面必須安裝最新的nodejs
--注意安裝nodejs
穩(wěn)定版本
2. 安裝 cnpm
npm 可能安裝失敗建議先用
npm
安裝一下cnpm
用淘寶鏡像安裝https://npm.taobao.org
npm install -g cnpm --registry=https://registry.npm.taobao.org
3. 使用 npm/cnpm 命令安裝 angular/cli
npm install -g @angular/cli
# 或者
cnpm install -g @angular/cli
ng v
查看版本信息
4. 安裝插件
5. 安裝chrome擴展
</article>
用
augury
查看component
結構嗜逻,更方便調試
2.2 創(chuàng)建項目
# 創(chuàng)建項目
ng new my-app
cd my-app
# 運行項目
ng serve --open
2.3 目錄結構分析
app目錄(重點)
app
目錄是我們要編寫的代碼目錄。我們寫的代碼都是放在這個目錄缭召。
一個Angular
程序至少需要一個模塊和一個組件栈顷。在我們新建項目的時候命令行已經(jīng)默認生成出來了
-
app.component.ts
:這個文件表示組件, - 組件是
Angular
應用的基本構建模塊嵌巷,可以理解為一段帶有業(yè)務邏輯和數(shù)據(jù)的Html
我們來看看app.component.ts
中的代碼萄凤,并解釋下代碼的意義
/*這里是從Angular核心模塊里面引入了component裝飾器*/
import {Component} from '@angular/core';
/*用裝飾器定義了一個組件以及組件的元數(shù)據(jù) 所有的組件都必須使用這個裝飾器來注解*/
@Component({
/*組件元數(shù)據(jù) Angular會通過這里面的屬性來渲染組件并執(zhí)行邏輯
* selector就是css選擇器,表示這個組件可以通過app-root來調用晴竞,index.html中有個<app-root>Loading...</app-root>標簽蛙卤,這個標簽用來展示該組件的內容
*templateUrl 組件的模板,定義了組件的布局和內容
*styleUrls 該模板引用那個css樣式
* */
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
/*AppComponent本來就是一個普通的typescript類,但是上面的組件元數(shù)據(jù)裝飾器告訴Angular颤难,AppComponent是一個組件神年,需要把一些元數(shù)據(jù)附加到這個類上,Angular就會把AppComponent當組件來處理*/
export class AppComponent {
/*這個類實際上就是該組件的控制器行嗤,我們的業(yè)務邏輯就是在這個類中編寫*/
title = '學習Angular';
}
組件相關的概念
- 組件元數(shù)據(jù)裝飾器(
@Component
)
簡稱組件裝飾器已日,用來告知Angular
框架如何處理一個TypeScript
類.
Component
裝飾器包含多個屬性,這些屬性的值叫做元數(shù)據(jù)栅屏,Angular
會根據(jù)這些元數(shù)據(jù)的值來渲染組件并執(zhí)行組件的邏輯 - 模板(
Template
)
我們可以通過組件自帶的模板來定義組件的外觀飘千,模板以html
的形式存在,告訴Angular
如何來渲染組件栈雳,一般來說护奈,模板看起來很像html
,但是我們可以在模板中使用Angular
的數(shù)據(jù)綁定語法哥纫,來呈現(xiàn)控制器中的數(shù)據(jù)霉旗。 - 控制器(
controller
)
控制器就是一個普通的typescript
類,他會被@Component
來裝飾蛀骇,控制器會包含組件所有的屬性和方法厌秒,絕大多數(shù)的業(yè)務邏輯都是寫在控制器里的秃嗜×《校控制器通過數(shù)據(jù)綁定與模板來通訊,模板展現(xiàn)控制器的數(shù)據(jù)概疆,控制器處理模板上發(fā)生的事件暑诸。
裝飾器蚌讼,模板和控制器是組件的必備要素。還有一些可選的元素屠列,比如:
- 輸入屬性(
@inputs
):是用來接收外部傳入的數(shù)據(jù)的,Angular
的程序結構就是一個組件樹啦逆,輸入屬性允許在組件樹種傳遞數(shù)據(jù)
提供器(providers
):這個是用來做依賴注入的 - 生命周期鉤子(
LifeCycle Hooks
):一個組件從創(chuàng)建到銷毀的過程中會有多個鉤子會被觸發(fā)伞矩,類似于Android中的Activity
的生命周期 - 樣式表:組件可以關聯(lián)一些樣式表
- 動畫(
Animations
):Angular
提供了一個動畫包來幫助我們方便的創(chuàng)建一些跟組件相關的動畫效果笛洛,比如淡入淡出等 - 輸出屬性(
@Outputs
):用來定義一些其他組件可能需要的事件或者用來在組件之間共享數(shù)據(jù)
組件的中關系就如下圖所示
下面我們來看看模塊文件
-
app.module.ts
:這個文件表示模塊 - 與
AppComponent
類似,模塊也需要裝飾器來裝飾
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeroesComponent } from './heroes/heroes.component';
@NgModule({
declarations: [
// 聲明模塊里有什么東西 只能聲明:組件/指令/管道
AppComponent,
HeroesComponent
],
// 聲明該模塊所依賴的模塊
imports: [
BrowserModule,
AppRoutingModule
],
// 默認情況下是空的
providers: [],
// 聲明模塊的主組件是什么
bootstrap: [AppComponent]
})
export class AppModule { }
2.4 Angular cli
通過
ng g
列出當前命令
1. 創(chuàng)建新組件 ng generate component component-name
ng g component components/header
指定生成到哪個目錄
該命令會把生成的組件乃坤,添加到 src/app/app.module.ts
文件中 @NgModule
的 declarations
列表中聲明
2. 使用 Angular CLI 創(chuàng)建一個名叫 hero 的服務
ng generate service hero
該命令會在
src/app/hero.service.ts
中生成HeroService
類的骨架苛让。HeroService
類的代碼如下:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class HeroService {
constructor() { }
}
3. 添加 AppRoutingModule
ng generate module app-routing --flat --module=app
-
--flat
把這個文件放進了src/app
中,而不是單獨的目錄中湿诊。 -
--module=app
告訴CLI
把它注冊到AppModule
的imports
數(shù)組中狱杰。
生成的文件是這樣的:
src/app/app-routing.module.ts (generated)
content_copy
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
@NgModule({
imports: [
CommonModule
],
declarations: []
})
export class AppRoutingModule { }
修改后
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
const routes: Routes = [];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
三、angular組件及組件里的模板
3.1 創(chuàng)建angualr組件
1. 創(chuàng)建組件
ng g component components/header
2. 使用組件
<app-header></app-header>
3.2 Angular 綁定數(shù)據(jù)
1. 數(shù)據(jù)文本綁定
定義數(shù)據(jù)幾種方式
<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 數(shù)據(jù)循環(huán) *ngFor
*1. ngFor 普通循環(huán)
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. 循環(huán)的時候設置 key
<ul>
<li *ngFor="let item of list;let i = index;"> <!-- 把索引index賦給i -->
{{item}} --{{i}}
</li> </ul>
3. template 循環(huán)數(shù)據(jù)
<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">訂單已經(jīng)確認</li> <li *ngSwitchCase="3">已發(fā)貨</li>
<li *ngSwitchDefault>無效</li>
</ul>
3.8 執(zhí)行事件 (click)=”getData()”
<button class="button" (click)="getData()"> 點擊按鈕觸發(fā)事件
</button>
<button class="button" (click)="setData()"> 點擊按鈕設置數(shù)據(jù)
</button>
getData(){ /*自定義方法獲取數(shù)據(jù)*/ //獲取
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 雙向數(shù)據(jù)綁定
<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
)是用來對輸入的數(shù)據(jù)進行處理仿畸,如大小寫轉換、數(shù)值和日期格式化等
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. 小數(shù)位數(shù)
接收的參數(shù)格式為
{最少整數(shù)位數(shù)}.{最少小數(shù)位數(shù)}-{最多小數(shù)位數(shù)}
<!--保留2~4位小數(shù)-->
<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
屬性 - 實現(xiàn)
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>
7.3 RepeatPipe 定義
import {Pipe, PipeTransform} from '@angular/core';
[@Pipe](/user/Pipe)({name: 'repeat'})
export class RepeatPipe implements PipeTransform {
transform(value: any, times: number) {
return value.repeat(times);
}
}
7.4 RepeatPipe 使用
<div>
<p ngNonBindable>
{{ 'lo' | repeat:3 }}
</p>
<p>
{{ 'lo' | repeat:3 }}
</p>
<!-- Output: lololo -->
</div>
3.13 實現(xiàn)一個人員登記表單-案例
# 創(chuàng)建組件
ng g component components/form
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.scss']
})
export class FormComponent implements OnInit {
public peopleInfo:any = {
username: '',
sex: '2',
cityList: ['北京', '上海', '深圳'],
city: '上海',
hobby:[{
title: '吃飯',
checked:false
},{
title:'睡覺',
checked:false
},{
title:'敲代碼',
checked:true
}],
mark:''
}
constructor() { }
ngOnInit() {
}
doSubmit(){
/*
jquery dom操作
<input type="text" id="username" />
let usernameDom:any=document.getElementById('username');
console.log(usernameDom.value);
*/
console.log(this.peopleInfo);
}
}
<h2>人員登記系統(tǒng)</h2>
<div class="people_list">
<ul>
<li>姓 名:<input type="text" id="username" [(ngModel)]="peopleInfo.username" value="fonm_input" /></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 peopleInfo.cityList">{{item}}</option>
</select>
</li>
<li>
愛 好:
<span *ngFor="let item of peopleInfo.hobby;let key=index;">
<input type="checkbox" [id]="'check'+key" [(ngModel)]="item.checked"/> <label [for]="'check'+key"> {{item.title}}</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>
<br>
<br>
<br>
<br>
<pre>
{{peopleInfo | json}}
</pre>
</div>
h2{
text-align: center;
}
.people_list{
width: 400px;
margin: 40px auto;
padding:20px;
border:1px solid #eee;
li{
height: 50px;
line-height: 50px;
.fonm_input{
width: 300px;
height: 28px;
}
}
.submit{
width: 100px;
height: 30px;
float: right;
margin-right: 50px;
margin-top:120px;
}
}
3.14 實現(xiàn)一個完整的ToDo-案例
基礎版
# 創(chuàng)建組件
ng g component components/todo
<h2>todoList</h2>
<div class="todolist">
<input class="form_input" type="text" [(ngModel)]="keyword" (keyup)="doAdd($event)" />
<hr>
<h3>待辦事項</h3>
<ul>
<li *ngFor="let item of todolist;let key=index;" [hidden]="item.status==1">
<input type="checkbox" [(ngModel)]="item.status" /> {{item.title}} ------ <button (click)="deleteData(key)">X</button>
</li>
</ul>
<h3>已完成事項</h3>
<ul>
<li *ngFor="let item of todolist;let key=index;" [hidden]="item.status==0">
<input type="checkbox" [(ngModel)]="item.status" /> {{item.title}} ------ <button (click)="deleteData(key)">X</button>
</li>
</ul>
</div>
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-todo',
templateUrl: './todo.component.html',
styleUrls: ['./todo.component.scss']
})
export class TodoComponent implements OnInit {
public keyword: string;
public todolist: any[] = [];
constructor() { }
ngOnInit() {
}
doAdd(e){
if(e.keyCode == 13){
if(!this.todolistHasKeyword(this.todolist, this.keyword)){
this.todolist.push({
title: this.keyword,
status: 0 //0表示代辦事項 1表示已完成事項
});
this.keyword='';
}else{
alert('數(shù)據(jù)已經(jīng)存在');
this.keyword='';
}
}
}
deleteData(key){
this.todolist.splice(key,1);
}
//如果數(shù)組里面有keyword返回true 否則返回false
todolistHasKeyword(todolist:any, keyword:any){
//異步 會存在問題
// todolist.forEach(value => {
// if(value.title==keyword){
// return true;
// }
// });
if(!keyword) return false;
for(var i=0; i<todolist.length; i++){
if(todolist[i].title==keyword){
return true;
}
}
return false;
}
}
h2{
text-align: center;
}
.todolist{
width: 400px;
margin: 20px auto;
.form_input{
margin-bottom: 20px;
width: 300px;
height: 32px;
}
li{
line-height: 60px;
}
}
3.15 搜索緩存數(shù)據(jù)-案例
基礎版
# 創(chuàng)建組件
ng g component components/search
<div class="search">
<input type="text" [(ngModel)]="keyword" /> <button (click)="doSearch()">搜索</button>
<hr>
<ul>
<li *ngFor="let item of historyList;let key=index;">{{item}} ------ <button (click)="deleteHistroy(key)">X</button></li>
</ul>
</div>
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.scss']
})
export class SearchComponent implements OnInit {
public keyword: string;
public historyList: any[] = [];
constructor() { }
ngOnInit() {
}
doSearch(){
if(this.historyList.indexOf(this.keyword)==-1){
this.historyList.push(this.keyword);
}
this.keyword = '';
}
deleteHistroy(key){
alert(key);
this.historyList.splice(key,1);
}
}
.search{
width: 400px;
margin: 20px auto;
input{
margin-bottom: 20px;
width: 300px;
height: 32px;
}
button{
height: 32px;
width: 80px;
}
}
四错沽、Angular 中的服務
4.1 服務
定義公共的方法簿晓,使得方法在組件之間共享調用
1. 創(chuàng)建服務命令
ng g service my-new-service
# 創(chuàng)建到指定目錄下面
ng g service services/storage
2. app.module.ts 里面引入創(chuàng)建的服務
// app.module.ts 里面引入創(chuàng)建的服務
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);
}
4.2 改造上面的Todo千埃、searchList
searchList
import { Component, OnInit } from '@angular/core';
// 引入服務
import { StorageService } from '../../services/storage.service';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.scss']
})
export class SearchComponent implements OnInit {
public keyword: string;
public historyList: any[] = [];
constructor(public storage: StorageService) {
console.log(this.storage.get());
}
ngOnInit() {
// 修改的地方
var searchlist:any=this.storage.get('searchlist');
if(searchlist){
this.historyList=searchlist;
}
}
doSearch(){
if(this.historyList.indexOf(this.keyword)==-1){
this.historyList.push(this.keyword);
// 修改的地方
this.storage.set('searchlist',this.historyList);
}
this.keyword = '';
}
deleteHistroy(key){
alert(key);
this.historyList.splice(key,1);
}
}
TODOLIST
ngOnInit() {
// 修改的地方
var todolist:any=this.storage.get('todolist');
if(todolist){
this.todolist=todolist;
}
}
doAdd(e){
if(e.keyCode==13){
if(!this.todolistHasKeyword(this.todolist,this.keyword)){
this.todolist.push({
title:this.keyword,
status:0 //0表示代辦事項 1表示已完成事項
});
this.keyword='';
// 修改的地方
this.storage.set('todolist',this.todolist); //用到this一定要注意this指向
}else{
alert('數(shù)據(jù)已經(jīng)存在');
this.keyword='';
}
}
}
// 修改的地方
checkboxChange(){
console.log('事件觸發(fā)了');
this.storage.set('todolist',this.todolist);
}
<h2>todoList</h2>
<div class="todolist">
<input class="form_input" type="text" [(ngModel)]="keyword" (keyup)="doAdd($event)" />
<hr>
<h3>待辦事項</h3>
<ul>
<li *ngFor="let item of todolist;let key=index;" [hidden]="item.status==1">
<!-- add checkboxChange-->
<input type="checkbox" [(ngModel)]="item.status" (change)="checkboxChange()"/> {{item.title}} ------ <button (click)="deleteData(key)">X</button>
</li>
</ul>
<h3>已完成事項</h3>
<ul>
<li *ngFor="let item of todolist;let key=index;" [hidden]="item.status==0">
<!-- add checkboxChange-->
<input type="checkbox" [(ngModel)]="item.status" (change)="checkboxChange()" /> {{item.title}} ------ <button (click)="deleteData(key)">X</button>
</li>
</ul>
</div>
五憔儿、Dom 操作以及@ViewChild、 執(zhí)行 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
和剛才的子組件關聯(lián)起來
@ViewChild('footerChild') footer
在父組件中調用子組件方法
run(){
this.footer.footerRun();
}
六放可、Angular 父子組件以及組件之間通訊
6.1 父組件給子組件傳值-@input
父組件不僅可以給子組件傳遞簡單的數(shù)據(jù)谒臼,還可把自己的方法以及整個父組件傳給子組件
1. 父組件調用子組件的時候傳入數(shù)據(jù)
<app-header [msg]="msg"></app-header>
2. 子組件引入 Input 模塊
import { Component, OnInit ,Input } from '@angular/core';
3. 子組件中 @Input 接收父組件傳過來的數(shù)據(jù)
export class HeaderComponent implements OnInit {
@Input() msg:string
constructor() { }
ngOnInit() {
}
}
4. 子組件中使用父組件的數(shù)據(jù)
<p>
child works!
{{msg}}
</p>
5. 把整個父組件傳給子組件
通過
this
傳遞整個組件實例
<app-header [home]="this"></app-header>
export class HeaderComponent implements OnInit {
@Input() home:any
constructor() { }
ngOnInit() {
}
}
執(zhí)行父組件方法
this.home.xxx()
6.2 子組件通過@Output 觸發(fā)父組件的方法(了解)
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 實例廣播數(shù)據(jù)
sendParent(){
// alert('zhixing');
this.outer.emit('msg from child')
}
4. 父組件調用子組件的時候,定義接收事件 , outer 就是子組件的 EventEmitter 對象 outer
<!--$event就是子組件emit傳遞的數(shù)據(jù)-->
<app-header (outer)="runParent($event)"></app-header>
5. 父組件接收到數(shù)據(jù)會調用自己的 runParent 方法耀里,這個時候就能拿到子組件的數(shù)據(jù)
//接收子組件傳遞過來的數(shù)據(jù)
runParent(msg:string){
alert(msg);
}
6.3 父組件通過@ViewChild 主動獲取子組 件的數(shù)據(jù)和方法
1. 調用子組件給子組件定義一個名稱
<app-footer #footerChild></app-footer>
2. 引入 ViewChild
import { Component, OnInit ,ViewChild} from '@angular/core';
3. ViewChild 和剛才的子組件關聯(lián)起來
@ViewChild('footerChild') footer;
4. 調用子組件
run(){ this.footer.footerRun();
}
6.4 非父子組件通訊
- 公共的服務
-
Localstorage
(推薦) Cookie
七蜈缤、Angular 中的生命周期函數(shù)
7.1 Angular中的生命周期函數(shù)
- 生命周期函數(shù)通俗的講就是組件創(chuàng)建、組件更新冯挎、組件銷毀的時候會觸發(fā)的一系列的方法劫樟。
- 當
Angular
使用構造函數(shù)新建一個組件或指令后,就會按下面的順序在特定時刻調用這些 生命周期鉤子方法织堂。 - 每個接口都有唯一的一個鉤子方法叠艳,它們的名字是由接口名再加上
ng
前綴構成的,比如OnInit
接口的鉤子方法叫做ngOnInit
.
1. 生命周期鉤子分類
基于指令與組件的區(qū)別來分類
指令與組件共有的鉤子
ngOnChanges
ngOnInit
ngDoCheck
ngOnDestroy
組件特有的鉤子
ngAfterContentInit
ngAfterContentChecked
ngAfterViewInit
ngAfterViewChecked
2. 生命周期鉤子的作用及調用順序
1易阳、ngOnChanges
- 當數(shù)據(jù)綁定輸入屬性的值發(fā)生變化時調用
2附较、ngOnInit
- 在第一次 ngOnChanges
后調用
3、ngDoCheck
- 自定義的方法潦俺,用于檢測和處理值的改變
4拒课、ngAfterContentInit
- 在組件內容初始化之后調用
5、ngAfterContentChecked
- 組件每次檢查內容時調用
6事示、ngAfterViewInit
- 組件相應的視圖初始化之后調用
7早像、ngAfterViewChecked
- 組件每次檢查視圖時調用
8、ngOnDestroy
- 指令銷毀前調用
3. 首次加載生命周期順序
export class LifecircleComponent {
constructor() {
console.log('00構造函數(shù)執(zhí)行了---除了使用簡單的值對局部變量進行初始化之外肖爵,什么都不應該做')
}
ngOnChanges() {
console.log('01ngOnChages執(zhí)行了---當被綁定的輸入屬性的值發(fā)生變化時調用(父子組件傳值的時候會觸發(fā))');
}
ngOnInit() {
console.log('02ngOnInit執(zhí)行了--- 請求數(shù)據(jù)一般放在這個里面');
}
ngDoCheck() {
console.log('03ngDoCheck執(zhí)行了---檢測卢鹦,并在發(fā)生 Angular 無法或不愿意自己檢測的變化時作出反應');
}
ngAfterContentInit() {
console.log('04ngAfterContentInit執(zhí)行了---當把內容投影進組件之后調用');
}
ngAfterContentChecked() {
console.log('05ngAfterContentChecked執(zhí)行了---每次完成被投影組件內容的變更檢測之后調用');
}
ngAfterViewInit() : void {
console.log('06 ngAfterViewInit執(zhí)行了----初始化完組件視圖及其子視圖之后調用(dom操作放在這個里面)');
}
ngAfterViewChecked() {
console.log('07ngAfterViewChecked執(zhí)行了----每次做完組件視圖和子視圖的變更檢測之后調用');
}
ngOnDestroy() {
console.log('08ngOnDestroy執(zhí)行了····');
}
//自定義方法
changeMsg() {
this.msg = "數(shù)據(jù)改變了";
}
}
帶
check
的可以對數(shù)據(jù)做響應操作
<button (click)="changeMsg()">數(shù)據(jù)改變了</button>
<input type='text' [(ngModel)]="userInfo" />
點擊按鈕/雙向數(shù)據(jù)綁定此時觸發(fā)了以下生命周期。只要數(shù)據(jù)改變
可以在
check
做一些操作
ngDoCheck() {
//寫一些自定義的操作
console.log('03ngDoCheck執(zhí)行了---檢測劝堪,并在發(fā)生 Angular 無法或不愿意自己檢測的變化時作出反應');
if(this.userinfo!==this.oldUserinfo){
console.log(`你從${this.oldUserinfo}改成${this.userinfo}`);
this.oldUserinfo = this.userinfo;
}else{
console.log("數(shù)據(jù)沒有變化");
}
}
7.2 生命周期鉤子詳解
7.2.1 constructor-掌握
constructor
冀自,來初始化類。Angular
中的組件就是基于class
類實現(xiàn)的秒啦,在Angular
中熬粗,constructor
用于注入依賴。組件的構造函數(shù)會在所有的生命周期鉤子之前被調用余境,它主要用于依賴注入或執(zhí)行簡單的數(shù)據(jù)初始化操作驻呐。
import { Component, ElementRef } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>Welcome to Angular World</h1>
<p>Hello {{name}}</p>
`,
})
export class AppComponent {
name: string = '';
constructor(public elementRef: ElementRef) {//使用構造注入的方式注入依賴對象
// 執(zhí)行初始化操作
this.name = 'Semlinker';
}
}
7.2.2 ngOnChanges()
當
Angular
(重新)設置數(shù)據(jù)綁定輸入屬性時響應灌诅。該 方法接受當前和上一屬性值的SimpleChanges
對象 當被綁定的輸入屬性的值發(fā)生變化時調用,首次調用一 定會發(fā)生在ngOnInit()
之前含末。
<!-- 父組件中 傳遞title屬性給header子組件 -->
<app-header [title]="title"></app-header>
此時改變
title
會觸發(fā)ngOnChanges
生命周期延塑,并且也會觸發(fā)
7.2.3 ngOnInit()--掌握
在
Angular
第一次顯示數(shù)據(jù)綁定和設置指令/組件的輸入屬性之后,初始化指令/組件答渔。在第一輪ngOnChanges()
完成之后調用关带,只調用一次≌铀海可以請求數(shù)據(jù)
-
使用 ngOnInit() 有兩個原因:
- 在構造函數(shù)之后馬上執(zhí)行復雜的初始化邏輯
- 在
Angular
設置完輸入屬性之后宋雏,對該組件進行準備。有經(jīng)驗的開發(fā)者會認同組件的構建應該很便宜和安全
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'exe-child',
template: `
<p>父組件的名稱:{{pname}} </p>
`
})
export class ChildComponent implements OnInit {
@Input()
pname: string; // 父組件的名稱
constructor() {
console.log('ChildComponent constructor', this.pname);
// Output:undefined
}
ngOnInit() {
console.log('ChildComponent ngOnInit', this.pname);
// output: 輸入的pname值
}
}
7.2.4 ngDoCheck()
檢測务豺,并在發(fā)生
Angular
無法或不愿意自己檢測的變 化時作出反應磨总。在每個Angular
變更檢測周期中調用,ngOnChanges()
和ngOnInit()
之后笼沥。
7.2.5 ngAfterContentInit()
當把內容投影進組件之后調用蚪燕。第一次
ngDoCheck()
之后調用,只調用一次
7.2.6 ngAfterContentChecked()
每次完成被投影組件內容的變更檢測之后調用奔浅。
ngAfterContentInit()
和每次ngDoCheck()
之后調
7.2.7 ngAfterViewInit()--掌握
初始化完組件視圖及其子視圖之后調用馆纳。第一 次
ngAfterContentChecked()
之后調用,只調用一次汹桦。在這里可以操作DOM
7.2.8 ngAfterViewChecked()
每次做完組件視圖和子視圖的變更檢測之后調用鲁驶。
ngAfterViewInit()
和每次ngAfterContentChecked()
之后 調用。
7.2.9 ngOnDestroy()--掌握
當
Angular
每次銷毀指令/組件之前調用并清掃舞骆。在這兒反訂閱可觀察對象和分離事件處理器钥弯,以防內存泄 漏。在Angular
銷毀指令/組件之前調用督禽。比如:移除事件監(jiān)聽脆霎、清除定時器、退訂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 異步數(shù)據(jù)流編程
8.1 Rxjs介紹
RxJS
是ReactiveX
編程理念的JavaScript
版本。ReactiveX
來自微軟虱岂,它是一種針對異步數(shù)據(jù) 流的編程玖院。簡單來說,它將一切數(shù)據(jù)第岖,包括HTTP
請求,DOM
事件或者普通數(shù)據(jù)等包裝成流的形式试溯,然后用強大豐富的操作符對流進行處理蔑滓,使你能以同步編程的方式處理異步數(shù)據(jù),并組合不同的操作符來輕松優(yōu)雅的實現(xiàn)你所需要的功能。
-
RxJS
是一種針對異步數(shù)據(jù)流編程工具键袱,或者叫響應式擴展編程;可不管如何解釋 RxJS 其目 標就是異步編程燎窘,Angular
引入RxJS
為了就是讓異步可控、更簡單蹄咖。 -
RxJS
里面提供了很多模塊褐健。這里我們主要給大家講RxJS
里面最常用的Observable
和 fromEvent
目前常見的異步編程的幾種方法:
- 回調函數(shù)
- 事件監(jiān)聽/發(fā)布訂閱
Promise
Rxjs
8.2 Promise和RxJS處理異步對比
新建一個
services
ng g service services/rxjs
在
services/rxjs.service.ts
中寫以下方法
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class RxjsService {
constructor() { }
// Promise 處理異步
getPromiseData() {
return new Promise(resolve = >{
setTimeout(() = >{
resolve('---promise timeout---');
},
2000);
});
// RxJS 處理異步:
getRxjsData() {
return new Observable(observer = >{
setTimeout(() = >{
observer.next('observable timeout');
},
2000);
});
}
}
// 在其他組件使用服務
import { Component, OnInit } from '@angular/core';
import { RxjsService } from '../../services/rxjs.service';
@Component({
selector: 'app-rxjs',
templateUrl: './rxjs.component.html',
styleUrls: ['./rxjs.component.scss']
})
export class RxjsComponent implements OnInit {
// 注入服務
constructor(public request: RxjsService) {
}
ngOnInit() {
// 調用方法
this.request.getRxjsData().subscribe(data=>{
console.log(data)
})
}
}
- 從上面列子可以看到
RxJS
和Promise
的基本用法非常類似,除了一些關鍵詞不同澜汤。Promise
里面用的是then()
和resolve()
蚜迅,而RxJS
里面用的是next()
和subscribe()
-
Rxjs
相比Promise
要強大很多。 比如Rxjs
中可以中途撤回俊抵、Rxjs
可以發(fā)射多個值谁不、Rxjs
提供了多種工具函數(shù)等等
8.3 Rxjs unsubscribe 取消訂閱
Promise
的創(chuàng)建之后,動作是無法撤回的徽诲。Observable
不一樣刹帕,動作可以通過unsbscribe()
方法中途撤回,而且Observable
在內部做了智能的處理.
Promise 創(chuàng)建之后動作無法撤回
let promise = new Promise(resolve = >{
setTimeout(() = >{
resolve('---promise timeout---');
},
2000);
});
promise.then(value = >console.log(value));
Rxjs 可以通過 unsubscribe() 可以撤回 subscribe 的動作
let stream = new Observable(observer = >{
let timeout = setTimeout(() = >{
clearTimeout(timeout);
observer.next('observable timeout');
},
2000);
});
let disposable = stream.subscribe(value = >console.log(value));
setTimeout(() = >{
//取消執(zhí)行 disposable.unsubscribe();
},
1000);
8.4 Rxjs 訂閱后多次執(zhí)行
- 如果我們想讓異步里面的方法多次執(zhí)行谎替,比如下面代碼偷溺。
這一點
Promise
是做不到的,對于Promise
來說钱贯,最終結果要么resole
(兌現(xiàn))亡蓉、要么reject
(拒絕),而且都只能觸發(fā)一次喷舀。如果在同一個Promise
對象上多次調用resolve
方法砍濒, 則會拋異常。而Observable
不一樣硫麻,它可以不斷地觸發(fā)下一個值爸邢,就像next()
這個方法的 名字所暗示的那樣。
let promise = new Promise(resolve = >{
setInterval(() = >{
resolve('---promise setInterval---');
},
2000);
});
promise.then(value = >console.log(value));
Rxjs
let stream = new Observable < number > (observer = >{
let count = 0;
setInterval(() = >{
observer.next(count++);
},
1000);
});
stream.subscribe(value = >console.log("Observable>" + value));
8.5 Angualr6.x之前使用Rxjs的工具函數(shù) map filter
注意:
Angular6
以后使用以前的rxjs
方法拿愧,必須安裝rxjs-compat
模塊才可以使用map
杠河、filter
方法。
angular6
后官方使用的是RXJS6
的新特性浇辜,所以官方給出了一個可以暫時延緩我們不需要修 改rsjx
代碼的辦法
npm install rxjs-compat
import {Observable} from 'rxjs'; import 'rxjs/Rx';
let stream = new Observable < any > (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));
8.6 Angualr6.x 以后 Rxjs6.x 的變化以及 使用
8.6.1 Rxjs 的變化參考
從
Angular5
升級到Angular6
券敌,angular6
相比較于angular5
總體變化不大,但是在RXJS
上面卻有一些變動柳洋,下面給大家講講關于Angular6
版本升級和RXJS6
新特性的講解
1. angular6 Angular7中使用以前的rxjs
對于寫了半年多的項目待诅,模塊已經(jīng)很多了,所以不可能在升級到
angular6
后馬上更新所有代碼關于RXJS6
的新特性熊镣,所以官方給出了一個可以暫時延緩我們不需要修改rsjx
代碼的辦法卑雁。
npm install --save rxjs-compat
- 優(yōu)點: 暫時不用改代碼募书,可以一點點地改,直到改完后吧這個包卸掉
-
缺點: 對于
rxjs6
的rename
的operator
無效测蹲,所以莹捡,如果有用到rename
的API
,必須手動修改
2. Angular6 以后 RXJS6的變化
RXJS6
改變了包的結構扣甲,主要變化在import
方式和operator
上面以及使用pipe()
2.1 Imports 方式改變
從
rxjs
中類似像導入observable
subject
等的不再進一步導入篮赢,而是止于rxjs
,rxjs6
在包的結構上進行了改變
2.2 operator的改變
總而言之: 類似于創(chuàng)建之類的用的
API
都是從rxjs
引入的,類似于map
之類的操作都是從rxjs/operators
引入的
2.3 pipeable observable
2.4 被重新命名的API
RXJS6
改變了包的結構琉挖,主要變化在import
方式和operator
上面以及使用pipe()
import {Observable} from 'rxjs';
import {map,filter} from 'rxjs/operators';
let stream= new Observable<any>(observer => {
let count = 0;
setInterval(() = >{
observer.next(count++);
},
1000);
});
stream.pipe(filter(val = >val % 2 == 0))
.subscribe(value = >console.log("filter>" + value));
stream
.pipe(
filter(val = >val % 2 == 0),
map(value = >{
return value * value
}))
.subscribe(value = >console.log("map>" + value));
8.7 Rxjs 延遲執(zhí)行
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`));
九启泣、Angular 中的數(shù)據(jù)交互(get jsonp post)
9.1 Angular get 請求數(shù)據(jù)
Angular5.x
以后get
、post
和和服務器交互使用的是HttpClientModule
模塊粹排。
1. 在 app.module.ts 中引入 HttpClientModule 并注入
import {HttpClientModule} from '@angular/common/http';
imports: [
BrowserModule,
HttpClientModule
]
2. 在用到的地方引入 HttpClient 并在構造函數(shù)聲明
import {HttpClient} from "@angular/common/http";
constructor(public http:HttpClient) { }
3. get 請求數(shù)據(jù)
var api = "http://a.itying.com/api/productlist";
this.http.get(api).subscribe(response => {
console.log(response); });
9.2 Angular post 提交數(shù)據(jù)
Angular5.x
以后get
种远、post
和和服務器交互使用的是HttpClientModule
模塊。
1. 在 app.module.ts 中引入 HttpClientModule 并注入
import {HttpClientModule} from '@angular/common/http';
imports: [
BrowserModule,
HttpClientModule
]
2. 在用到的地方引入 HttpClient顽耳、HttpHeaders 并在構造函數(shù)聲明 HttpClient
import {HttpClient,HttpHeaders} from "@angular/common/http";
constructor(public http:HttpClient) { }
- post 提交數(shù)據(jù)
用express搭建一個server
// package.json
{
"dependencies": {
"ejs": "^2.5.6",
"express": "^4.15.3",
"socket.io": "^2.0.3",
"body-parser": "~1.17.1"
}
}
// app.js 代碼
var express = require('express');
var app=express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
/express允許跨域/
app.all('', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "");
res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By",' 3.2.1')
if(req.method=="OPTIONS") res.send(200);
else next();
});
//app.use(express.static(path.join(__dirname, 'public')));
app.get('/',function(req,res){
res.send('首頁');
})
app.post('/dologin',function(req,res){
console.log(req.body);
res.json({"msg":'post成功'});
})
app.get('/news',function(req,res){
//console.log(req.body);
res.jsonp({"msg":'這是新聞數(shù)據(jù)'});
})
app.listen(3000,'127.0.0.1',function(){
console.log('項目啟動在3000端口')
});
// angular代碼
doLogin() {
// 手動設置請求類型
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
var api = "http://127.0.0.1:3000/doLogin";
this.http.post(api, {
username: '張三',
age: '20'
},
httpOptions).subscribe(response = >{
console.log(response);
});
}
9.3 Angular Jsonp 請求數(shù)據(jù)
- 在 app.module.ts 中引入 HttpClientModule坠敷、HttpClientJsonpModule 并注入
import {HttpClientModule,HttpClientJsonpModule} from '@angular/common/http';
imports: [
BrowserModule,
HttpClientModule,
HttpClientJsonpModule
]
- 在用到的地方引入 HttpClient 并在構造函數(shù)聲明
import {HttpClient} from "@angular/common/http";
constructor(public http:HttpClient) { }
- jsonp 請求數(shù)據(jù)
// 接口支持jsonp請求
var api = "http://a.itying.com/api/productlist";
this.http.jsonp(api,'callback').subscribe(response => {
console.log(response); });
9.4 Angular 中使用第三方模塊 axios 請求數(shù)據(jù)
- 安裝 axios
cnpm install axios --save
- 用到的地方引入 axios
import axios from 'axios';
- 看文檔使用
axios.get('/user?ID=12345').then(function(response) {
// handle success
console.log(response);
}).
catch(function(error) {
// handle error console.log(error);
}).then(function() {
// always executed
});
十、Angular 中的路由
10.1 Angular 創(chuàng)建一個默認帶路由的項目
- 命令創(chuàng)建項目
ng new angualrdemo08 --skip-install
- 創(chuàng)建需要的組件
ng g component home
ng g component news
ng g component newscontent
- 找到 app-routing.module.ts 配置路由
// 引入組件
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'
} ];
- 找到 app.component.html 根組件模板射富,配置 router-outlet 顯示動態(tài)加載的路由
<h1>
<a routerLink="/home">首頁</a> <a routerLink="/news">新聞</a>
</h1>
<router-outlet></router-outlet>
10.2 routerLink 跳轉頁面 默認路由
<a routerLink="/home">首頁</a>
<a routerLink="/news">新聞</a>
//匹配不到路由的時候加載的組件 或者跳轉的路由
{
path: '', /任意的路由/
// component:HomeComponent
redirectTo:'home'
}
10.3 routerLinkActive 設置routerLink 默認選中路由
<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;
}
10.4 routerLink Get傳遞參數(shù)
- 跳轉
<li *ngFor="let item of list;let key=index;">
<a [routerLink]="['/news-detail']" [queryParams]="{aid:key}">{{key}}--{{item}}</a>
</li>
-
接收參數(shù)
import { ActivatedRoute } from '@angular/router';
constructor(public route:ActivatedRoute) { }
this.route.queryParams.subscribe((data)=>{
console.log(data);
})
10.5 動態(tài)路由
1.配置動態(tài)路由
const routes: Routes = [
{path: 'home', component: HomeComponent},
{path: 'news', component: NewsComponent},
{path: 'newscontent/:id', component: NewscontentComponent},
{
path: '',
redirectTo: '/home',
pathMatch: 'full'
} ];
- 跳轉傳值
<a [routerLink]="[ '/newscontent/',aid]">跳轉到詳情</a>
<a routerLink="/newscontent/{{aid}}">跳轉到詳情</a>
- 獲取動態(tài)路由的值
import { ActivatedRoute} from '@angular/router';
constructor( private route: ActivatedRoute) { }
ngOnInit() {
console.log(this.route.params);
this.route.params.subscribe(data=>this.id=data.id);
}
10.6 動態(tài)路由的 js 跳轉
// 引入
import { Router } from '@angular/router';
// 初始化
export class HomeComponent implements OnInit {
constructor(private router: Router) {}
ngOnInit() {}
goNews(){
// this.router.navigate(['/news', hero.id]);
this.router.navigate(['/news']);
}
}
// 路由跳轉
this.router.navigate(['/news', hero.id]);
10.7 路由 get 傳值 js 跳轉
- 引入 NavigationExtras
import { Router ,NavigationExtras} from '@angular/router';
- 定義一個 goNewsContent 方法執(zhí)行跳轉膝迎,用 NavigationExtras 配置傳參。
goNewsContent() {
let navigationExtras: NavigationExtras = {
queryParams: {
'session_id': '123'
},
fragment: 'anchor'
};
this.router.navigate(['/news'], navigationExtras);
}
- 獲取 get 傳值
constructor(private route: ActivatedRoute) {
console.log(this.route.queryParams);
}
10.8 父子路由
- 創(chuàng)建組件引入組件
import { NewsaddComponent } from './components/newsadd/newsadd.component';
import { NewslistComponent } from './components/newslist/newslist.component';
- 配置路由
{
path: 'news',
component: NewsComponent,
children: [{
path: 'newslist',
component: NewslistComponent
},
{
path: 'newsadd',
component: NewsaddComponent
}]
}
- 父組件中定義 router-outlet
<router-outlet></router-outlet>