Angular 4 快速入門

2018-08-28 10:29 更新

查看新版 Angular 6.x 快速入門

目錄

  • 第一節(jié) - Angular 簡介
  • 第二節(jié) - Angular 環(huán)境搭建
  • 第三節(jié) - 插值表達式
  • 第四節(jié) - 自定義組件
  • 第五節(jié) - 常用指令簡介
  • 第六節(jié) - 事件綁定
  • 第七節(jié) - 表單模塊簡介
  • 第八節(jié) - Http 模塊簡介
  • 第九節(jié) - 注入服務(wù)
  • 第十節(jié) - 路由模塊簡介

第一節(jié) Angular 簡介

Angular 是什么

Angular 是由谷歌開發(fā)與維護一個開發(fā)跨平臺應(yīng)用程序的框架,同時適用于手機與桌面。

Angular 有什么特點

  • 基于 Angular 我們可以構(gòu)建適用于所有平臺的應(yīng)用。比如:Web 應(yīng)用、移動 Web 應(yīng)用、移動應(yīng)用和桌面應(yīng)用等。
  • 通過 Web Worker和服務(wù)端渲染 (SSR),達到在如今Web平臺上所能達到的最高渲染速度。
  • Angular 讓你能夠有效掌控可伸縮性?;?RxJS、Immutable.js 和其它推送模型,能適應(yīng)海量數(shù)據(jù)需求。

Angular 提供了哪些功能

  • 動態(tài)HTML
  • 強大的表單系統(tǒng) (模板驅(qū)動和模型驅(qū)動)
  • 強大的視圖引擎
  • 事件處理
  • 快速的頁面渲染
  • 靈活的路由
  • HTTP 服務(wù)
  • 視圖封裝
  • AOT、Tree Shaking

Angular 與 AngularJS 有什么區(qū)別

  • 不再有ControllerScope
  • 更好的組件化及代碼復用
  • 降低了學習曲線
  • 更好的移動端支持
  • 引入了 RxJSObservable
  • 引入了 Zone.js,提供更加智能的變化檢測

第二節(jié) - Angular 環(huán)境搭建

基礎(chǔ)要求

Angular 開發(fā)環(huán)境配置方式

配置開發(fā)環(huán)境

本快速入門教程,選用第一種配置方式搭建 Angular 開發(fā)環(huán)境:

  • 使用 Git 克隆 quickstart 項目

git clone https://github.com/angular/quickstart ng4-quickstart

code ./ng4-quickstart

  • 安裝項目所需依賴

npm i 

  • 驗證環(huán)境是否搭建成功

npm start

第三節(jié) - 插值表達式

在 Angular 中,我們可以使用 {{}} 插值語法實現(xiàn)數(shù)據(jù)綁定。

綁定普通文本

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


@Component({
  selector: 'my-app',
  template: `<h1>Hello {{name}}</h1>`,
})
export class AppComponent  {
  name = 'Angular'; 
}

綁定對象屬性

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


@Component({
  selector: 'my-app',
  template: `
    <h2>大家好,我是{{name}}</h2>
    <p>我來自<strong>{{address.province}}</strong>省,
      <strong>{{address.city}}</strong>市
    </p>
  `,
})
export class AppComponent {
  name = 'Semlinker';
  address = {
    province: '福建',
    city: '廈門'
  }
}

值得一提的是,我們可以使用 Angular 內(nèi)置的 json 管道,來顯示對象信息:

@Component({
  selector: 'my-app',
  template: `
    ...
    <p>{{address | json}}</p>
  `,
})
export class AppComponent {
  name = 'Semlinker';
  address = {
    province: '福建',
    city: '廈門'
  }
}

第四節(jié) - 自定義組件

在 Angular 中,我們可以通過 Component 裝飾器和自定義組件類來創(chuàng)建自定義組件。

基礎(chǔ)知識

定義組件的元信息

在 Angular 中,我們可以使用 Component 裝飾器來定義組件的元信息:

@Component({
  selector: 'my-app', // 用于定義組件在HTML代碼中匹配的標簽
  template: `<h1>Hello {{name}}</h1>`, // 定義組件內(nèi)嵌視圖
})

定義組件類

export class AppComponent  {
  name = 'Angular'; 
}

定義數(shù)據(jù)接口

在 TypeScript 中的接口是一個非常靈活的概念,除了可用于對類的一部分行為進行抽象以外,也常用于對「對象的形狀(Shape)」進行描述。

interface Person {
  name: string;
  age: number;
}


let semlinker: Person = {
  name: 'semlinker',
  age: 31
};

自定義組件示例

創(chuàng)建 UserComponent 組件

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


@Component({
    selector: 'sl-user',
    template: `
    <h2>大家好,我是{{name}}</h2>
    <p>我來自<strong>{{address.province}}</strong>省,
      <strong>{{address.city}}</strong>市
    </p>
    `
})
export class UserComponent {
    name = 'Semlinker';
    address = {
        province: '福建',
        city: '廈門'
    };
}

聲明 UserComponent 組件

// ...
import { UserComponent } from './user.component';
@NgModule({
  imports:      [ BrowserModule ],
  declarations: [ AppComponent, UserComponent],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

使用 UserComponent 組件

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


@Component({
  selector: 'my-app',
  template: `
    <sl-user></sl-user>
  `,
})
export class AppComponent {}

使用構(gòu)造函數(shù)初始化數(shù)據(jù)

@Component({...})
export class UserComponent {
    name: string;
    address: any;


    constructor() {
        this.name = 'Semlinker';
        this.address = {
            province: '福建',
            city: '廈門'
        }
    }
}

接口使用示例

定義 Address 接口

interface Address {
    province: string;
    city: string;
}

使用 Address 接口

export class UserComponent {
    name: string;
    address: Address;
    // ...
}

第五節(jié) - 常用指令簡介

在 Angular 實際項目中,最常用的指令是 ngIfngFor 指令。

基礎(chǔ)知識

ngIf 指令簡介

該指令用于根據(jù)表達式的值,動態(tài)控制模板內(nèi)容的顯示與隱藏。它與 AngularJS 1.x 中的 ng-if 指令的功能是等價的。

ngIf 指令語法

<div *ngIf="condition">...</div>

ngFor 指令簡介

該指令用于基于可迭代對象中的每一項創(chuàng)建相應(yīng)的模板。它與 AngularJS 1.x 中的 ng-repeat 指令的功能是等價的。

ngFor 指令語法

<li *ngFor="let item of items;">...</li>

ngIf 與 ngFor 指令使用示例

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


interface Address {
    province: string;
    city: string;
}


@Component({
    selector: 'sl-user',
    template: `
    <h2>大家好,我是{{name}}</h2>
    <p>我來自<strong>{{address.province}}</strong>省,
      <strong>{{address.city}}</strong>市
    </p>
    <div *ngIf="showSkills">
        <h3>我的技能</h3>
        <ul>
            <li *ngFor="let skill of skills">
                {{skill}}
            </li>
        </ul>
    </div>
    `
})
export class UserComponent {
    name: string;
    address: Address;
    showSkills: boolean;
    skills: string[];


    constructor() {
        this.name = 'Semlinker';
        this.address = {
            province: '福建',
            city: '廈門'
        };
        this.showSkills = true;
        this.skills = ['AngularJS 1.x', 'Angular 2.x', 'Angular 4.x'];
    }
}

第六節(jié) - 事件綁定

在 Angular 中,我們可以通過 (eventName) 的語法,實現(xiàn)事件綁定。

基礎(chǔ)知識

事件綁定語法

<date-picker (dateChanged)="statement()"></date-picker>

等價于

<date-picker on-dateChanged="statement()"></date-picker>

介紹完事件綁定的語法,接下來我們來為第五節(jié)中的 UserComponent 組件,開發(fā)一個功能,即可以讓用戶動態(tài)控制技能信息的顯示與隱藏。

事件綁定示例

@Component({
    selector: 'sl-user',
    template: `
    ...
    <button (click)="toggleSkills()">
        {{ showSkills ? "隱藏技能" : "顯示技能" }}
    </button>
    ...
    `
})
export class UserComponent {
    // ...
    toggleSkills() {
        this.showSkills = !this.showSkills;
    }
}

第七節(jié) - 表單模塊簡介

Angular 中有兩種表單:

  • Template Driven Forms - 模板驅(qū)動式表單 (類似于 AngularJS 1.x 中的表單 )
  • Reactive Forms - 響應(yīng)式表單

本小節(jié)主要介紹模板驅(qū)動式的表單,接下來我們來演示如何通過表單來為我們的之前創(chuàng)建的 UserComponent 組件,增加讓用戶自定義技能的功能。

基礎(chǔ)知識

導入表單模塊

import { FormsModule } from '@angular/forms';
// ...
@NgModule({
  imports: [BrowserModule, FormsModule],
  declarations: [AppComponent, UserComponent],
  bootstrap: [AppComponent]
})
export class AppModule { }

模板變量語法

<video #player></video> 
<button (click)="player.pause()">Pause</button>

等價于

<video ref-player></video>

表單使用示例

@Component({
    selector: 'sl-user',
    template: `
    ...
    <div *ngIf="showSkills">
        <h3>我的技能</h3>
        ...
        <form (submit)="addSkill(skill.value)">
            <label>添加技能</label>
            <input type="text" #skill>
        </form>
    </div>
    `
})
export class UserComponent {
   // ...
    addSkill(skill: string) {
        let skillStr = skill.trim();
        if (this.skills.indexOf(skillStr) === -1) {
            this.skills.push(skillStr);
        }
    }
}

第八節(jié) - Http 模塊簡介

基礎(chǔ)知識

導入 Http 模塊

// ... 
import { HttpModule } from '@angular/http';


@NgModule({
  imports: [BrowserModule, FormsModule, HttpModule],
  declarations: [AppComponent, UserComponent],
  bootstrap: [AppComponent]
})
export class AppModule { }

使用 Http 服務(wù)步驟

(1) 從 @angular/http 模塊中導入 Http 類

(2) 導入 RxJS 中的 map 操作符

(3) 使用 DI 方式注入 http 服務(wù)

(4) 調(diào)用 http 服務(wù)的 get() 方法,設(shè)置請求地址并發(fā)送 HTTP 請求

(5) 調(diào)用 Response 對象的 json() 方法,把響應(yīng)體轉(zhuǎn)成 JSON 對象

(6) 把請求的結(jié)果,賦值給對應(yīng)的屬性

Http 服務(wù)使用示例

使用 Http 服務(wù)

import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http'; // (1)
import 'rxjs/add/operator/map'; // (2)


interface Member {
    id: string;
    login: string;
    avatar_url: string;
}


@Component({
    selector: 'sl-members',
    template: `
    <h3>Angular Orgs Members</h3>
    <ul *ngIf="members">
      <li *ngFor="let member of members;">
        <p>
          <img [src]="member.avatar_url" width="48" height="48"/>
          ID:<span>{{member.id}}</span>
          Name: <span>{{member.login}}</span>
        </p>
      </li>
    </ul>
    `
})
export class MembersComponent implements OnInit {
  members: Member[];


  constructor(private http: Http) { } // (3)


  ngOnInit() {
    this.http.get(`https://api.github.com/orgs/angular/members?page=1&per_page=5`) // (4)
        .map(res => res.json()) // (5)
        .subscribe(data => {
           if (data) this.members = data; // (6)
        });
    }
}

聲明 MembersComponent 組件

// ...
import { MembersComponent } from './members.component';


@NgModule({
  imports: [BrowserModule, FormsModule, HttpModule],
  declarations: [AppComponent, UserComponent, MembersComponent],
  bootstrap: [AppComponent]
})
export class AppModule { }

使用 MembersComponent 組件

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


@Component({
  selector: 'my-app',
  template: `
    <sl-members></sl-members>
  `,
})
export class AppComponent {}

第九節(jié) - 注入服務(wù)

基礎(chǔ)知識

組件中注入服務(wù)步驟

(1) 配置已創(chuàng)建的服務(wù),如:

@NgModule({
  // ...
  providers: [MemberService]
})
export class AppModule { }

(2) 導入已創(chuàng)建的服務(wù),如:

import { MemberService } from '../member.service';

(3) 使用構(gòu)造注入方式,注入服務(wù):

export class MembersComponent implements OnInit {
   // ...
   constructor(private memberService: MemberService) { }
}

服務(wù)使用示例

創(chuàng)建 MemberService 服務(wù)

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


@Injectable()
export class MemberService {
    constructor(private http: Http) { }


    getMembers() {
        return this.http
            .get(`https://api.github.com/orgs/angular/members?page=1&per_page=5`)
            .map(res => res.json())
    }
}

配置 MemberService 服務(wù)

import { MemberService } from "./member.service";


@NgModule({
  // ...
  providers:[MemberService],
  bootstrap: [AppComponent]
})
export class AppModule { }

使用 MemberService 服務(wù)

// ...
import { MemberService } from "./member.service";


@Component({...})
export class MembersComponent implements OnInit {
    members: Member[];


    constructor(private memberService: MemberService) { }


    ngOnInit() {
        this.memberService.getMembers()
            .subscribe(data => {
                if (data) this.members = data;
            });
    }
}

第十節(jié) - 路由模塊簡介

基礎(chǔ)知識

導入路由模塊

// ...
import { RouterModule } from '@angular/router';


@NgModule({
  imports: [BrowserModule, FormsModule, HttpModule, RouterModule],
  declarations: [AppComponent, UserComponent, MembersComponent],
  bootstrap: [AppComponent]
})
export class AppModule { }

配置路由信息

import { Routes, RouterModule } from '@angular/router';
import { UserComponent } from './user.component';


export const ROUTES: Routes = [
  { path: 'user', component: UserComponent }
];


@NgModule({
  imports: [
    BrowserModule,
    RouterModule.forRoot(ROUTES)
  ],
  // ...
})
export class AppModule {}

routerLink 指令

為了讓我們鏈接到已設(shè)置的路由,我們需要使用 routerLink 指令,具體示例如下:

<nav>
  <a routerLink="/">首頁</a>
  <a routerLink="/user">我的</a>
</nav>

當我們點擊以上的任意鏈接時,頁面不會被重新加載。反之,我們的路徑將在 URL 地址欄中顯示,隨后進行后續(xù)視圖更新,以匹配 routerLink 中設(shè)置的值。

router-outlet 指令

該指令用于告訴 Angular 在哪里加載組件,當 Angular 路由匹配到響應(yīng)路徑,并成功找到需要加載的組件時,它將動態(tài)創(chuàng)建對應(yīng)的組件,并將其作為兄弟元素,插入到 router-outlet 元素中。具體示例如下:

@Component({
  selector: 'app-root',
  template: `
    <div class="app">
      <h3>Our app</h3>
      <router-outlet></router-outlet>
    </div>
  `
})
export class AppComponent {}

路由使用示例

配置路由信息

export const ROUTES: Routes = [
  { path: '', pathMatch: 'full', redirectTo: 'user' },
  { path: 'user', component: UserComponent },
  { path: 'members', component: MembersComponent }
];


@NgModule({
  imports: [BrowserModule, FormsModule, HttpModule,
    RouterModule.forRoot(ROUTES)],
  // ...
})
export class AppModule { }

配置路由導航

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


@Component({
  selector: 'my-app',
  template: `
    <div class="app">
      <h1>歡迎來到Angular的世界</h1>
      <nav>
        <a routerLink="/user">我的</a>
        <a routerLink="/members">Angular成員</a>
      </nav>
      <router-outlet></router-outlet>
    </div>
  `,
})
export class AppComponent { }

完整示例

AppModule

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule, Routes } from '@angular/router';


import { AppComponent } from './app.component';
import { UserComponent } from './user.component';
import { MembersComponent } from './members.component';
import { MemberService } from "./member.service";


export const ROUTES: Routes = [
  { path: '', pathMatch: 'full', redirectTo: 'user' },
  { path: 'user', component: UserComponent },
  { path: 'members', component: MembersComponent }
];


@NgModule({
  imports: [BrowserModule, FormsModule, HttpModule,
    RouterModule.forRoot(ROUTES)],
  declarations: [AppComponent, UserComponent, MembersComponent],
  providers: [MemberService],
  bootstrap: [AppComponent]
})
export class AppModule { }

AppComponent

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


@Component({
  selector: 'my-app',
  template: `
    <div class="app">
      <h1>歡迎來到Angular的世界</h1>
      <nav>
        <a routerLink="/user">我的</a>
        <a routerLink="/members">Angular成員</a>
      </nav>
      <router-outlet></router-outlet>
    </div>
  `,
})
export class AppComponent { }

UserComponent

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




interface Address {
    province: string;
    city: string;
}


@Component({
    selector: 'sl-user',
    template: `
    <h2>大家好,我是{{name}}</h2>
    <p>我來自<strong>{{address.province}}</strong>省,
      <strong>{{address.city}}</strong>市
    </p>
    <button (click)="toggleSkills()">
        {{ showSkills ? "隱藏技能" : "顯示技能" }}
    </button>
    <div *ngIf="showSkills">
        <h3>我的技能</h3>
        <ul>
            <li *ngFor="let skill of skills">
                {{skill}}
            </li>
        </ul>
        <form (submit)="addSkill(skill.value)">
            <label>添加技能</label>
            <input type="text" #skill>
        </form>
    </div>
    `
})
export class UserComponent {
    name: string;
    address: Address;
    showSkills: boolean;
    skills: string[];


    constructor() {
        this.name = 'Semlinker';
        this.address = {
            province: '福建',
            city: '廈門'
        };
        this.showSkills = true;
        this.skills = ['AngularJS 1.x', 'Angular 2.x', 'Angular 4.x'];
    }


    toggleSkills() {
        this.showSkills = !this.showSkills;
    }


    addSkill(skill: string) {
        let skillStr = skill.trim();
        if (this.skills.indexOf(skillStr) === -1) {
            this.skills.push(skillStr);
        }
    }
}

MembersComponent

import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';


import { MemberService } from "./member.service";


interface Member {
    id: string;
    login: string;
    avatar_url: string;
}


@Component({
    selector: 'sl-members',
    template: `
    <h3>Angular Orgs Members</h3>
    <ul *ngIf="members">
      <li *ngFor="let member of members;">
        <p>
          <img [src]="member.avatar_url" width="48" height="48"/>
          ID:<span>{{member.id}}</span>
          Name: <span>{{member.login}}</span>
        </p>
      </li>
    </ul>
    `
})
export class MembersComponent implements OnInit {
    members: Member[];


    constructor(private memberService: MemberService) { }


    ngOnInit() {
        this.memberService.getMembers()
            .subscribe(data => {
                if (data) this.members = data;
            });
    }
}

MemberService

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


@Injectable()
export class MemberService {
    constructor(private http: Http) { }


    getMembers() {
        return this.http
            .get(`https://api.github.com/orgs/angular/members?page=1&per_page=5`)
            .map(res => res.json())
    }
}

我有話說

除了本系列教程外,還有其它學習資源么?

本系列教程的主要目的是讓初學者對 Angular 的相關(guān)基礎(chǔ)知識,有一定的了解。除了本系列教程外,初學者還可以參考以下教程:

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號