查看新版 Angular 6.x 快速入門
Angular 是由谷歌開發(fā)與維護一個開發(fā)跨平臺應(yīng)用程序的框架,同時適用于手機與桌面。
Controller
和 Scope
RxJS
與 Observable
Zone.js
,提供更加智能的變化檢測本快速入門教程,選用第一種配置方式搭建 Angular 開發(fā)環(huán)境:
Git
克隆 quickstart 項目git clone https://github.com/angular/quickstart ng4-quickstart
IDE
打開已新建的項目 (本教程使用的 IDE 是 Visual Studio Code)code ./ng4-quickstart
npm i
npm start
在 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: '廈門'
}
}
在 Angular 中,我們可以通過 Component
裝飾器和自定義組件類來創(chuàng)建自定義組件。
在 Angular 中,我們可以使用 Component
裝飾器來定義組件的元信息:
@Component({
selector: 'my-app', // 用于定義組件在HTML代碼中匹配的標簽
template: `<h1>Hello {{name}}</h1>`, // 定義組件內(nèi)嵌視圖
})
export class AppComponent {
name = 'Angular';
}
在 TypeScript 中的接口是一個非常靈活的概念,除了可用于對類的一部分行為進行抽象以外,也常用于對「對象的形狀(Shape)」進行描述。
interface Person {
name: string;
age: number;
}
let semlinker: Person = {
name: 'semlinker',
age: 31
};
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: '廈門'
};
}
// ...
import { UserComponent } from './user.component';
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent, UserComponent],
bootstrap: [ AppComponent ]
})
export class AppModule { }
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<sl-user></sl-user>
`,
})
export class AppComponent {}
@Component({...})
export class UserComponent {
name: string;
address: any;
constructor() {
this.name = 'Semlinker';
this.address = {
province: '福建',
city: '廈門'
}
}
}
interface Address {
province: string;
city: string;
}
export class UserComponent {
name: string;
address: Address;
// ...
}
在 Angular 實際項目中,最常用的指令是 ngIf
和 ngFor
指令。
該指令用于根據(jù)表達式的值,動態(tài)控制模板內(nèi)容的顯示與隱藏。它與 AngularJS 1.x 中的 ng-if
指令的功能是等價的。
<div *ngIf="condition">...</div>
該指令用于基于可迭代對象中的每一項創(chuàng)建相應(yīng)的模板。它與 AngularJS 1.x 中的 ng-repeat
指令的功能是等價的。
<li *ngFor="let item of items;">...</li>
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'];
}
}
在 Angular 中,我們可以通過 (eventName)
的語法,實現(xiàn)事件綁定。
<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;
}
}
Angular 中有兩種表單:
本小節(jié)主要介紹模板驅(qū)動式的表單,接下來我們來演示如何通過表單來為我們的之前創(chuàng)建的 UserComponent
組件,增加讓用戶自定義技能的功能。
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);
}
}
}
// ...
import { HttpModule } from '@angular/http';
@NgModule({
imports: [BrowserModule, FormsModule, HttpModule],
declarations: [AppComponent, UserComponent],
bootstrap: [AppComponent]
})
export class AppModule { }
(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)的屬性
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)
});
}
}
// ...
import { MembersComponent } from './members.component';
@NgModule({
imports: [BrowserModule, FormsModule, HttpModule],
declarations: [AppComponent, UserComponent, MembersComponent],
bootstrap: [AppComponent]
})
export class AppModule { }
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<sl-members></sl-members>
`,
})
export class AppComponent {}
(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) { }
}
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())
}
}
import { MemberService } from "./member.service";
@NgModule({
// ...
providers:[MemberService],
bootstrap: [AppComponent]
})
export class AppModule { }
// ...
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;
});
}
}
// ...
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 {}
為了讓我們鏈接到已設(shè)置的路由,我們需要使用 routerLink 指令,具體示例如下:
<nav>
<a routerLink="/">首頁</a>
<a routerLink="/user">我的</a>
</nav>
當我們點擊以上的任意鏈接時,頁面不會被重新加載。反之,我們的路徑將在 URL 地址欄中顯示,隨后進行后續(xù)視圖更新,以匹配 routerLink
中設(shè)置的值。
該指令用于告訴 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 { }
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 { }
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 { }
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);
}
}
}
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;
});
}
}
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ǔ)知識,有一定的了解。除了本系列教程外,初學者還可以參考以下教程:
更多建議: