Angular8入門(mén)教程

timg.jpeg

1. 環(huán)境搭建

0. Before

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

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

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

1. 安裝 Angular CLI

npm install -g @angular/cli

安裝好之后,進(jìn)入到你的開(kāi)發(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)開(kāi)發(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. 在頁(yè)面渲染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. 添加按鈕

在頁(yè)面上添加按鈕

<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對(duì)象,加入到todoList數(shù)組中,這樣頁(yè)面上就顯示最新數(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ú)立的頂級(jí)模塊中加載和配置路由器,它專注于路由功能,然后由根模塊 AppModule 導(dǎo)入它。

1. 生成路由模塊

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

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

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

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

使用 RouterModule 中的 Routes 類來(lái)配置路由器,所以還要從 @angular/router 庫(kù)中導(dǎo)入這兩個(gè)符號(hào)。

添加一個(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)

打開(kāi) AppComponent 的模板,把里面代碼清空,替換為 <router-outlet> 元素。

<router-outlet></router-outlet>

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

4. 添加用戶頁(yè)面

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í),就可以切換頁(yè)面。

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: '湖南長(zhǎng)沙'},
    {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ù)訪問(wèn)的職責(zé)委托給某個(gè)服務(wù)。
服務(wù)可以實(shí)現(xiàn)在多個(gè)類之間共享數(shù)據(jù)。

2. 什么是依賴注入

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

依賴,是當(dāng)類需要執(zhí)行其功能時(shí),所需要的服務(wù)或?qū)ο蟆?DI 是一種編碼模式,其中的類會(huì)從外部源中請(qǐng)求獲取依賴,而不是自己創(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 符號(hào),并且給這個(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: '湖南長(zhǎng)沙'},
    {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方法,用來(lái)獲取用戶,代碼如下:

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 的單例對(duì)象。

創(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 通過(guò) HTTP 與遠(yuǎn)程服務(wù)器通訊的機(jī)制。
要讓 HttpClient 在應(yīng)用中隨處可用,

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

Http請(qǐng)求

修改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請(qǐng)求數(shù)據(jù):

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

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

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

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

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

7. 詳情頁(yè)

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

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

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}

在瀏覽器地址欄訪問(wèn):http://localhost:4200/detail,查看詳情頁(yè)面。

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. 展示詳情信息

獲取到用戶信息后,展示在詳情頁(yè)面:

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

6. 返回按鈕

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

8. 管道(過(guò)濾器)

管道類似于vue中的過(guò)濾器
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)換后的值。
    *可以通過(guò) @Pipe 裝飾器來(lái)告訴 Angular:這是一個(gè)管道。該裝飾器是從 Angular 的 core 庫(kù)中引入的。
  • 這個(gè) @Pipe 裝飾器允許你定義管道的名字,這個(gè)名字會(huì)被用在模板表達(dá)式中。它必須是一個(gè)有效的 JavaScript 標(biāo)識(shí)符。 比如,你這個(gè)管道的名字是 gender。

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

在用戶組件中使用:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容