Angular 4 快速入門

2018-08-28 10:29 更新

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

目錄

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

第一節(jié) Angular 簡介

Angular 是什么

Angular 是由谷歌開發(fā)與維護(hù)一個(gè)開發(fā)跨平臺(tái)應(yīng)用程序的框架,同時(shí)適用于手機(jī)與桌面。

Angular 有什么特點(diǎn)

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

Angular 提供了哪些功能

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

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

  • 不再有ControllerScope
  • 更好的組件化及代碼復(fù)用
  • 降低了學(xué)習(xí)曲線
  • 更好的移動(dòng)端支持
  • 引入了 RxJSObservable
  • 引入了 Zone.js,提供更加智能的變化檢測(cè)

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

基礎(chǔ)要求

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

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

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

  • 使用 Git 克隆 quickstart 項(xiàng)目

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

  • 使用 IDE 打開已新建的項(xiàng)目 (本教程使用的 IDE 是 Visual Studio Code)

code ./ng4-quickstart

  • 安裝項(xiàng)目所需依賴

npm i 

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

npm start

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

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

綁定普通文本

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


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

綁定對(duì)象屬性

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 管道,來顯示對(duì)象信息:

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

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

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

基礎(chǔ)知識(shí)

定義組件的元信息

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

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

定義組件類

export class AppComponent  {
  name = 'Angular'; 
}

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

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

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 實(shí)際項(xiàng)目中,最常用的指令是 ngIfngFor 指令。

基礎(chǔ)知識(shí)

ngIf 指令簡介

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

ngIf 指令語法

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

ngFor 指令簡介

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

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) 的語法,實(shí)現(xiàn)事件綁定。

基礎(chǔ)知識(shí)

事件綁定語法

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

等價(jià)于

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

介紹完事件綁定的語法,接下來我們來為第五節(jié)中的 UserComponent 組件,開發(fā)一個(gè)功能,即可以讓用戶動(dòng)態(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ū)動(dòng)式表單 (類似于 AngularJS 1.x 中的表單 )
  • Reactive Forms - 響應(yīng)式表單

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

基礎(chǔ)知識(shí)

導(dǎo)入表單模塊

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>

等價(jià)于

<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ǔ)知識(shí)

導(dǎo)入 Http 模塊

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


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

使用 Http 服務(wù)步驟

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

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

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

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

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

(6) 把請(qǐng)求的結(jié)果,賦值給對(duì)應(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ǔ)知識(shí)

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

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

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

(2) 導(dǎo)入已創(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ǔ)知識(shí)

導(dǎo)入路由模塊

// ...
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>

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

router-outlet 指令

該指令用于告訴 Angular 在哪里加載組件,當(dāng) Angular 路由匹配到響應(yīng)路徑,并成功找到需要加載的組件時(shí),它將動(dòng)態(tài)創(chuàng)建對(duì)應(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 { }

配置路由導(dǎo)航

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())
    }
}

我有話說

除了本系列教程外,還有其它學(xué)習(xí)資源么?

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

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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)