Angular8入門教程

timg.jpeg

1. 環(huán)境搭建

0. Before

在開始之前,請確保你的開發(fā)環(huán)境中包括 Node.js? 和 npm 包管理器。

Angular 需要 Node.js 版本 10.9.0 或更高版本。

要檢查你的版本闭树,請?jiān)诮K端/控制臺(tái)窗口中運(yùn)行 node -v 。

1. 安裝 Angular CLI

npm install -g @angular/cli

安裝好之后棉圈,進(jìn)入到你的開發(fā)目錄,使用腳手架創(chuàng)建項(xiàng)目:

ng new my-app

進(jìn)入到項(xiàng)目根目錄,啟動(dòng)項(xiàng)目:

cd my-app
ng serve --open

ng serve 命令會(huì)啟動(dòng)開發(fā)服務(wù)器烈涮、監(jiān)視文件,并在這些文件發(fā)生更改時(shí)重建應(yīng)用窖剑。

2. 項(xiàng)目目錄結(jié)構(gòu)

https://www.angular.cn/guide/file-structure

3. 核心概念

https://www.angular.cn/guide/architecture

  • 模塊
  • 組件
  • 服務(wù)與依賴注入
  • 路由

2. Start from TodoList

1. 新建TodoList組件

ng generate component TodoList

2. 創(chuàng)建Todo類

在app下新建Todo.js

export class Todo {
    id :number;
    name : string;
}

3. 創(chuàng)建todoList數(shù)組

在todo-list.component.ts中導(dǎo)入Todo.js

import {Todo} from '../Todo';

創(chuàng)建todoList數(shù)組:

 todoList: Todo[] = [
    {id:0,name:"aaaa"},
    {id:1,name:"bbbb"},
    {id:2,name:"cccc"},
    {id:3,name:"dddd"},
    {id:4,name:"eeee"}
  ];

4. 在頁面渲染todolist列表

<ul>
   <li *ngFor="let todo of todoList">
       <span>{{todo.id}}</span>  {{todo.name}}
   </li>
</ul>

5. 添加輸入框

在 app.module.ts中導(dǎo)入FormsModule:

import {FormsModule} from '@angular/forms';

并且添加到 imports中:

 imports: [
    BrowserModule,
    FormsModule
  ],

在todo-list.component.ts中添加:

@Input() text: string;

然后在src/app/todo-list/todo-list.component.html 添加輸入框:

<input type="text"  [(ngModel)]="text">

使用 [(ngModel)]="text"進(jìn)行雙向數(shù)據(jù)綁定坚洽,類似vue中的v-model
這樣就可以實(shí)時(shí)獲取用戶的輸入。

6. 添加按鈕

在頁面上添加按鈕

<button (click)="addTodo()"> 添加 </button>

按鈕綁定了addTodo事件西土,我們需要實(shí)現(xiàn)這個(gè)方法讶舰,
在src/app/todo-list/todo-list.component.ts中添加:

  addTodo(): void {
    if(this.text){
      this.todoList.push({
        id: this.todoList.length,
        name: this.text
      })
      this.text = ''
    }
  }

這樣當(dāng)用戶輸入后,點(diǎn)擊添加按鈕需了,就會(huì)把用戶數(shù)據(jù)構(gòu)造成Todo對象跳昼,加入到todoList數(shù)組中,這樣頁面上就顯示最新數(shù)據(jù)了援所。

7. 刪除

在每一行todo后添加刪除按鈕

 <span>{{todo.id}}</span>  {{todo.name}}  <span (click)="deleteTodo(todo.id)">delete</span>

刪除按鈕綁定了deleteTodo方法庐舟,同時(shí)把當(dāng)前數(shù)據(jù)id傳入欣除,
deleteTodo的實(shí)現(xiàn):

 deleteTodo(id): void {
 this.todoList = this.todoList.filter(todo => todo.id != id)
}

3. 路由

在 Angular 中住拭,最好在一個(gè)獨(dú)立的頂級模塊中加載和配置路由器,它專注于路由功能,然后由根模塊 AppModule 導(dǎo)入它滔岳。

1. 生成路由模塊

ng generate module app-routing --flat --module=app

--flat 把這個(gè)文件放進(jìn)了 src/app 中杠娱,而不是單獨(dú)的目錄中。

--module=app 告訴 CLI 把它注冊到 AppModule 的 imports 數(shù)組中谱煤。

通常不會(huì)在路由模塊中聲明組件摊求,所以可以刪除 @NgModule.declarations 并刪除對 CommonModule 的引用。

使用 RouterModule 中的 Routes 類來配置路由器刘离,所以還要從 @angular/router 庫中導(dǎo)入這兩個(gè)符號室叉。

添加一個(gè) @NgModule.exports 數(shù)組,其中放上 RouterModule 硫惕。 導(dǎo)出 RouterModule 讓路由器的相關(guān)指令可以在 AppModule 中的組件中使用茧痕。

此刻的 AppRoutingModule 是這樣的:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';


@NgModule({
  exports: [
    RouterModule
  ]
})
export class AppRoutingModule { }

2. 添加路由定義

路由定義 會(huì)告訴路由器,當(dāng)用戶點(diǎn)擊某個(gè)鏈接或者在瀏覽器地址欄中輸入某個(gè) URL 時(shí)恼除,要顯示哪個(gè)視圖踪旷。

典型的 Angular 路由(Route)有兩個(gè)屬性:

  1. path:一個(gè)用于匹配瀏覽器地址欄中 URL 的字符串。

  2. component:當(dāng)導(dǎo)航到此路由時(shí)豁辉,路由器應(yīng)該創(chuàng)建哪個(gè)組件令野。

const route: Routes = [
  {path: 'todo', component: TodoListComponent}
];

把 RouterModule 添加到 @NgModule.imports 數(shù)組中

imports: [
    RouterModule.forRoot(route),
  ]

現(xiàn)在完整代碼變成這樣:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import {TodoListComponent} from './todo-list/todo-list.component';


const route: Routes = [
  {path: 'todo', component: TodoListComponent}
];

@NgModule({
  imports: [
    RouterModule.forRoot(route),
  ],
  exports: [RouterModule],
})
export class AppRoutingModule { }

3. 添加路由出口 (RouterOutlet)

打開 AppComponent 的模板,把里面代碼清空徽级,替換為 <router-outlet> 元素气破。

<router-outlet></router-outlet>

這個(gè)就相當(dāng)于vue中的 <router-view></router-view>

4. 添加用戶頁面

1. 新建一個(gè)用戶組件

ng generate component User

2. 修改路由,添加user路由:

const route: Routes = [
  {path: 'todo', component: TodoListComponent},
  {path: 'user', component: UserComponent},
];

3. 在src/app/app.component.html上添加導(dǎo)航:

  <a routerLink="/todo">todo</a>
  <a routerLink="/user">user</a>

這樣當(dāng)用戶點(diǎn)擊導(dǎo)航鏈接時(shí)餐抢,就可以切換頁面堵幽。

4. 設(shè)置默認(rèn)導(dǎo)航,添加:

在 a標(biāo)簽上添加 [routerLinkActive]="'active'",并且添加 .active

.active
    color: #369
    border-bottom: solid 2px #369;
 <nav>
    <a routerLink="/todo" [routerLinkActive]="'active'">todo</a>
    <a routerLink="/user" [routerLinkActive]="'active'">user</a>
  </nav>

5. 添加User類

在app下新建 User.ts

export class User {
    id: number;
    name: string;
    gender: boolean;
    addr: string;
}

修改 src/app/user/user.component.ts,添加users弹澎,代碼如下:

import { Component, OnInit } from '@angular/core';
import {User} from '../User';

@Component({
  selector: 'app-user',
  templateUrl: './user.component.html',
  styleUrls: ['./user.component.styl']
})
export class UserComponent implements OnInit {

  users: User[] = [
    {id: 0, name: '鋼鐵俠', gender: true, addr: '湖南長沙'},
    {id: 1, name: '雪諾', gender: true, addr: '北境'},
    {id: 2, name: '黑寡婦', gender: false, addr: '重啟'},
    {id: 3, name: '孫悟空', gender: true, addr: '花果山'},
    {id: 4, name: '潘金蓮', gender: false, addr: '四川成都'},
  ];
  constructor() { }

  ngOnInit() {
  }

}

在 src/app/user/user.component.html 中渲染用戶列表:

<div>
    <h3>User List</h3>

    <ul>
        <li *ngFor="let u of users">
            {{u.name}} {{u.gender}} {{u.addr}}
        </li>
    </ul>
</div>

5. Service

1. 什么是服務(wù)

組件不應(yīng)該直接獲取或保存數(shù)據(jù)朴下,它們不應(yīng)該了解是否在展示假數(shù)據(jù)。 它們應(yīng)該聚焦于展示數(shù)據(jù)苦蒿,而把數(shù)據(jù)訪問的職責(zé)委托給某個(gè)服務(wù)殴胧。
服務(wù)可以實(shí)現(xiàn)在多個(gè)類之間共享數(shù)據(jù)。

2. 什么是依賴注入

依賴注入(DI)是一種重要的應(yīng)用設(shè)計(jì)模式佩迟。 Angular 有自己的 DI 框架团滥,在設(shè)計(jì)應(yīng)用時(shí)常會(huì)用到它,以提升它們的開發(fā)效率和模塊化程度报强。

依賴灸姊,是當(dāng)類需要執(zhí)行其功能時(shí),所需要的服務(wù)或?qū)ο蟆?DI 是一種編碼模式秉溉,其中的類會(huì)從外部源中請求獲取依賴力惯,而不是自己創(chuàng)建它們碗誉。

3. 創(chuàng)建可注入的服務(wù)

ng generate service user

這個(gè)令會(huì)在 src/app/user.service.ts 中生成 UserService 類的骨架。 UserService 類的代碼如下:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class UserService {

  constructor() { }
}

4. @Injectable() 服務(wù)

注意父晶,這個(gè)新的服務(wù)導(dǎo)入了 Angular 的 Injectable 符號哮缺,并且給這個(gè)服務(wù)類添加了 @Injectable() 裝飾器。 它把這個(gè)類標(biāo)記為依賴注入系統(tǒng)的參與者之一甲喝。UserService 類將會(huì)提供一個(gè)可注入的服務(wù)尝苇,并且它還可以擁有自己的待注入的依賴。

5. 創(chuàng)建模擬數(shù)據(jù)

在app下新建mock-users.ts,代碼如下:

import {User} from './user';

export const USERS: User[] = [
    {id: 0, name: '鋼鐵俠', gender: true, addr: '湖南長沙'},
    {id: 1, name: '雪諾', gender: true, addr: '北境'},
    {id: 2, name: '黑寡婦', gender: false, addr: '重啟'},
    {id: 3, name: '孫悟空', gender: true, addr: '花果山'},
    {id: 4, name: '潘金蓮', gender: false, addr: '四川成都'},
];

6. service的實(shí)現(xiàn)

修改src/app/user.service.ts代碼埠胖,添加getUsers方法糠溜,用來獲取用戶,代碼如下:

import { Injectable } from '@angular/core';
import {User} from './User';
import {USERS} from './mock-users';

@Injectable({
  providedIn: 'root'
})
export class UserService {

  constructor() { }

  getUsers(): User[] {
    return USERS;
  }
}

7. 注入service

src/app/user/user.component.ts中導(dǎo)入UserService:

import {UserService} from '../user.service';

往構(gòu)造函數(shù)中添加一個(gè)私有的 userService直撤,其類型為 UserService诵冒。

constructor(private userService: UserService) { }

這個(gè)參數(shù)同時(shí)做了兩件事:

  1. 聲明了一個(gè)私有 userService 屬性,
  2. 把它標(biāo)記為一個(gè) UserService 的注入點(diǎn)谊惭。

當(dāng) Angular 創(chuàng)建 UserComponent 時(shí)汽馋,依賴注入系統(tǒng)就會(huì)把這個(gè) userService 參數(shù)設(shè)置為 UserService 的單例對象。

創(chuàng)建一個(gè)函數(shù)圈盔,以從服務(wù)中獲取這些用戶數(shù)據(jù)豹芯,并在ngOnInit中調(diào)用:

 ngOnInit() {
    this.getUsers();
  }
  getUsers(): void {
    this.users = this.userService.getUsers();
  }

完整代碼如下:

import { Component, OnInit } from '@angular/core';
import {User} from '../User';
import {UserService} from '../user.service';

@Component({
  selector: 'app-user',
  templateUrl: './user.component.html',
  styleUrls: ['./user.component.styl']
})
export class UserComponent implements OnInit {

  users: User[] = [];
  constructor(private userService: UserService) { }

  ngOnInit() {
    this.getUsers();
  }
  getUsers(): void {
    this.users = this.userService.getUsers();
  }

}

6. http

啟用 HTTP 服務(wù)

HttpClient 是 Angular 通過 HTTP 與遠(yuǎn)程服務(wù)器通訊的機(jī)制。
要讓 HttpClient 在應(yīng)用中隨處可用驱敲,

  • 打開根模塊 AppModule铁蹈,
  • 從 @angular/common/http 中導(dǎo)入 HttpClientModule 符號,
  • 把它加入 @NgModule.imports 數(shù)組众眨。
import { HttpClientModule } from '@angular/common/http';

Http請求

修改src/app/user.service.ts,代碼如下:

import { Injectable } from '@angular/core';
import {User} from './User';
import {Observable, of} from 'rxjs';
import {HttpClient} from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class UserService {

  userUrl = 'https://www.fastmock.site/mock/37666f9c160ab4b9182191952fa5b988/cs/users';
  constructor(private http: HttpClient) { }

  getUsers(): Observable<User[]> {
    return this.http.get<User[]>(this.userUrl);
  }
}

在構(gòu)造函數(shù)中添加 http:

constructor(private http: HttpClient) { }

之后使用http請求數(shù)據(jù):

this.http.get<User[]>(this.userUrl);

由于數(shù)據(jù)請求是異步的握牧,所以使用ObservablegetUsers方法的返回值改為一個(gè)可觀察對象

調(diào)用服務(wù)

src/app/user/user.component.ts中調(diào)用服務(wù),獲取數(shù)據(jù)的結(jié)果現(xiàn)在是一個(gè)Observable對象娩梨,調(diào)用它的subscribe方法沿腰,當(dāng)數(shù)據(jù)請求成功后,在其回調(diào)中獲取數(shù)據(jù)狈定,代碼如下:

getUsers(): void {
    this.userService.getUsers()
    .subscribe( res => {
      this.users = res.users;
    });
}

7. 詳情頁

1. 創(chuàng)建詳情頁

在用戶列表點(diǎn)擊用戶颂龙,跳轉(zhuǎn)到用戶詳情頁。
首先創(chuàng)建詳情頁:

ng generate component UserDetail

2. 配置路由:

src/app/app-routing.module.ts中導(dǎo)入詳情組件:

import {UserDetailComponent} from './user-detail/user-detail.component';

添加路由配置:

{path: 'detail', component: UserDetailComponent}

在瀏覽器地址欄訪問:http://localhost:4200/detail,查看詳情頁面纽什。

3. 在用戶類表添加導(dǎo)航鏈接:

 <li *ngFor="let u of users">
    <a routerLink="/detail/{{u.id}}">
        {{u.name}} {{u.gender}} {{u.addr}}
    </a>
</li>

同時(shí)修改路由配置;

{path: 'detail/:id', component: UserDetailComponent}

這樣就可以把參數(shù) id傳遞到詳情組件措嵌,在詳情組件內(nèi)獲取參數(shù);

const id = this.route.snapshot.paramMap.get('id');

4. 調(diào)用service,獲取用戶詳情

添加獲取用戶的方法芦缰,調(diào)用service企巢,傳入用戶id,獲取單個(gè)用戶:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { UserService} from '../user.service';
import { User } from '../User';
@Component({
  selector: 'app-user-detail',
  templateUrl: './user-detail.component.html',
  styleUrls: ['./user-detail.component.styl']
})
export class UserDetailComponent implements OnInit {

  user: User;
  constructor(
    private route: ActivatedRoute,
    private userService: UserService
    ) { }

  ngOnInit() {
      this.getHero();
  }
  getHero(): void {
    const id = this.route.snapshot.paramMap.get('id');
    this.userService.getUsers()
    .subscribe( res => {
      this.user = res.users.find(user => user.id + '' === id);
    });
  }
}

5. 展示詳情信息

獲取到用戶信息后让蕾,展示在詳情頁面:

<div>
    <h3>用戶詳情</h3>
    <div *ngIf="user">
        <p>
            {{user.name}}
        </p>
        <p>
            {{user.gender}}
        </p>
        <p>
            {{user.addr}}
        </p>
    </div>
</div>

6. 返回按鈕

在詳情頁浪规,可以添加一個(gè)返回按鈕或听,點(diǎn)擊返回到上一頁:

8. 管道(過濾器)

管道類似于vue中的過濾器
Angular內(nèi)置的管道有:

  • DatePipe
  • UpperCasePipe
  • LowerCasePipe
  • CurrencyPipe
  • PercentPipe

使用實(shí)例:

<p>The hero's birthday is {{ birthday | date:"MM/dd/yy" }} </p>

串聯(lián)使用:

{{ birthday | date | uppercase}}

自定義管道

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({name: 'gender'})
export class GenderPipe implements PipeTransform {
  transform(value: boolean): string {
    return value ? '男' : '女';
  }
}

在這個(gè)管道的定義中體現(xiàn)了幾個(gè)關(guān)鍵點(diǎn):

  • 管道是一個(gè)帶有“管道元數(shù)據(jù)(pipe metadata)”裝飾器的類。
  • 這個(gè)管道類實(shí)現(xiàn)了 PipeTransform 接口的 transform 方法罗丰,該方法接受一個(gè)輸入值和一些可選參數(shù)神帅,并返回轉(zhuǎn)換后的值再姑。
    *可以通過 @Pipe 裝飾器來告訴 Angular:這是一個(gè)管道萌抵。該裝飾器是從 Angular 的 core 庫中引入的。
  • 這個(gè) @Pipe 裝飾器允許你定義管道的名字元镀,這個(gè)名字會(huì)被用在模板表達(dá)式中绍填。它必須是一個(gè)有效的 JavaScript 標(biāo)識符。 比如栖疑,你這個(gè)管道的名字是 gender讨永。

注意:
在使用之前必須把這個(gè)管道添加到 AppModule 的 declarations 數(shù)組中。

在用戶組件中使用:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末遇革,一起剝皮案震驚了整個(gè)濱河市卿闹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌萝快,老刑警劉巖锻霎,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異揪漩,居然都是意外死亡旋恼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門奄容,熙熙樓的掌柜王于貴愁眉苦臉地迎上來冰更,“玉大人,你說我怎么就攤上這事昂勒∈裣福” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵戈盈,是天一觀的道長审葬。 經(jīng)常有香客問我,道長奕谭,這世上最難降的妖魔是什么涣觉? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮血柳,結(jié)果婚禮上官册,老公的妹妹穿的比我還像新娘。我一直安慰自己难捌,他們只是感情好膝宁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布鸦难。 她就那樣靜靜地躺著,像睡著了一般员淫。 火紅的嫁衣襯著肌膚如雪合蔽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天介返,我揣著相機(jī)與錄音拴事,去河邊找鬼。 笑死圣蝎,一個(gè)胖子當(dāng)著我的面吹牛刃宵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播徘公,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼牲证,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了关面?” 一聲冷哼從身側(cè)響起坦袍,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎等太,沒想到半個(gè)月后捂齐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡澈驼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年辛燥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缝其。...
    茶點(diǎn)故事閱讀 39,703評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挎塌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出内边,到底是詐尸還是另有隱情榴都,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布漠其,位于F島的核電站嘴高,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏和屎。R本人自食惡果不足惜拴驮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望柴信。 院中可真熱鬧套啤,春花似錦、人聲如沸随常。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至唆鸡,卻和暖如春涝影,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背争占。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工燃逻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人燃乍。 一個(gè)月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓唆樊,卻偏偏與公主長得像宛琅,于是被迫代替她去往敵國和親刻蟹。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容