1.單向數據綁定的‘插值表達式’
angular中最典型的數據顯示方式:把HTML模板(template)的控件綁定到angular組件的屬性(component相當於一個構造函數,下面例子中的這個構造函數有name、title、和hero三個屬性)
簡單來說就是把組件的屬性名放到顯示曾{{屬性名}}中,angular負責噴到頁面中;angular從組件中提取屬性插入瀏覽器,然后angular會自動監聽這些屬性值的變化,一旦屬性值發生變化,angular會自動刷新顯示,這里的刷新,嚴格意義上指的是視圖事件發生之后,比如定時器運行等
注意:這里模板(template)使用的是ES6的多行字符串的語法,是一個反單引號,就是鍵盤數字1前面的那個~下面的符號,具體使用可以參照我博客園ES6新增語法中的內容
變量賦值的方法:
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: `<h1>{{title}}</h1><h2>{{hero}} details!</h2>`, }) export class AppComponent { name = 'Angular'; title='Tour of Heroes'; hero='Windstorm'; }
輸出
Tour of Heroes
Windstorm details!
-------------------------------------------------
同樣,和angular1相同,這里模板可以使用template來指定內聯的HTML模板片段,也可以使用templateUrl來指定外聯的HTML文件(這個HTML外聯文件的中的內容只是你需要渲染進頁面的一本分HTML片段,templateUrl的值是一個相對路徑)
相同的,也可以使用構造函數聲明和初始化屬性
構造函數聲明方法
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: ` <h1>{{title}}</h1> <h2>My favorite hero is :{{hero}}</h2> ` }) export class AppComponent { title:string; hero:string; constructor(){ this.title='Tour of Heroes'; this.hero='Windstrom'; } }
注意title:string;使用的是typescript的語法,表明定義變量,這個變量的值必須為string數據類型
2.ngFor顯示屬性(angular的迭代指令):*ngFor
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: ` <h1>{{title}}</h1> <h2>My favorite hero is :{{myHero}}</h2> <p>Heros:</p> <ul> <li *ngFor="let hero of heros">{{hero}}</li> </ul> ` }) export class AppComponent { title='Tour of Heroes'; heros=['Windstrom','Jason','andy']; myHero=this.heros[0] }
*ngFor='let hero of heros' 中的hero是一個模板輸入變量 相當於 name in item
簡單的說上述例子中的模板中的li可以換成<li *ngFor="let name of heros">{{name}}</li>
瀏覽器中的渲染結果如下
Tour of Heroes
My favorite hero is :Windstrom
Heros:
Windstrom
Jason
andy
為數據創建一個類
export class Hero{
constructor(public id:number, public name:string){
}
}
這里使用了ES6和TS的語法:創建了一個類Hero,這個類是一個構造函數,他有兩個屬性,一個是number類型值的屬性id和一個是string類型屬性的name,當我們new出這個實例的時候,這些屬性將會初始化相應的參數
下面來使用這個Hero類(注意先后順序,使用模板之前需要定義對象)
import { Component } from '@angular/core'; export class Hero{ constructor(public id:number, public name:string){ } } @Component({ selector: 'my-app', template: ` <h1>{{title}}</h1> <h2>My favorite hero is :{{myHero.name}}</h2> <p>Heros:</p> <ul> <li *ngFor="let hero of heros">{{hero.name}}</li> </ul> ` }) export class AppComponent { title='Tour of Heroes'; heros=[ new Hero(1,'Jason'), new Hero(2,'andy'), new Hero(3,'windStrom') ]; myHero=this.heros[0] }
3.ngIf:根據一個布爾值來進行顯示或移除一個元素,注意是DOM操作,增或者刪
<p *ngIf="heros.length>3">There are many heros!</p>
這個的意思表示如果heros的length大於3就創建一個p標簽,反之,不成立就是false就移除這個p標簽,注意ngIf中添加的只能是真假
4.雙向數據綁定
需要使用 FormsModule模塊,並且需要把它添加到NgModule裝飾器的imports數組中,該數組是如果是外部模塊,則需要引入,引入的方式就是上面第一句話:
import {FormsModule} from '@angular/forms'; app.module.ts文件 import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import {FormsModule} from '@angular/forms'; import { AppComponent } from './app.component'; @NgModule({ //入口模塊 imports: [BrowserModule,FormsModule], //生命文件 declarations:[AppComponent,HeroDetailComponent], //引導程序 bootstrap:[AppComponent] }) export class AppModule { } export class AppModule { }
app.component.ts文件中修改input標簽的雙向綁定為
<input type="text" value="" [(ngModel)]="heros.name" placeholder="name">
5.定義一個數組
export class Hero{ constructor(public id:number, public name:string){ } } const HEROES:Hero[]=[ {id:1,name:'Jason'}, {id:2,name:'xuekui'}, {id:3,name:'xiaoming'}, {id:4,name:'xiaohong'}, {id:5,name:'xiaoli'}, {id:6,name:'blue'}, {id:7,name:'green'}, {id:8,name:'orage'}, {id:9,name:'yellow'}, {id:10,name:'red'}, ];
Hero是一個數組的構造函數,HEROES是一個實例化的數組
暴漏數組(創建一個公共屬性,供綁定使用):heroes=HEROS; 這里沒有明確heros屬性的數據類型,TS有很強的隱式類型聲明系統(類型推測)
創建數組並循環噴入頁面
import { Component } from '@angular/core'; export class Hero{ constructor(public id:number, public name:string){ } } const HEROES:Hero[]=[ {id:1,name:'Jason'}, {id:2,name:'xuekui'}, {id:3,name:'xiaoming'}, {id:4,name:'xiaohong'}, {id:5,name:'xiaoli'}, {id:6,name:'blue'}, {id:7,name:'green'}, {id:8,name:'orage'}, {id:9,name:'yellow'}, {id:10,name:'red'} ]; @Component({ selector: 'my-app', template: ` <h1>{{title}}</h1> <h2>My Heroes</h2> <ul> <li *ngFor="let hero of Heroes"> <!--each hero goes here--> <span class="badge">{{hero.id}}</span>{{hero.name}} </li> </ul> ` }) export class AppComponent { title='Tour of Heroes'; Heroes=HEROES; }
7.為一個組件設置內聯樣式
在@Component裝飾器的styles屬性設置css類:使用ES6的反引號語法書寫多行字符串,注意,為一個組件指定樣式時,他們的作用域將僅限於該組件,不會泄露到外部HTML中。
styles: [` .selected { background-color: #CFD8DC !important; color: white; } .heroes { margin: 0 0 2em 0; list-style-type: none; padding: 0; width: 15em; } .heroes li { cursor: pointer; position: relative; left: 0; background-color: #EEE; margin: .5em; padding: .3em 0; height: 1.6em; border-radius: 4px; } .heroes li.selected:hover { background-color: #BBD8DC !important; color: white; } .heroes li:hover { color: #607D8B; background-color: #DDD; left: .1em; } .heroes .text { position: relative; top: -3px; } .heroes .badge { display: inline-block; font-size: small; color: white; padding: 0.8em 0.7em 0 0.7em; background-color: #607D8B; line-height: 1em; position: relative; left: -1px; top: -4px; height: 1.8em; margin-right: .8em; border-radius: 4px 0 0 4px; } `]
8.主從結構:主視圖---列表視圖,從視圖---被選中的結構的詳細信息視圖
點擊事件 (click)="函數名(參數)" 在點擊事件上綁定屬性鏈接主從視圖
[class.selected]="hero === selectedHero" 類名的選擇,當引號中為true的時候,類名添加,當引號中為false的時候,類名去除。
9.命名規范:我們的所有組件名都以Component結尾。所有組件的文件名都以.component結尾。
這里我們使用小寫中線命名法 (也叫烤串命名法)拼寫文件名, 所以不用擔心它在服務器或者版本控制系統中出現大小寫問題。
我們使用@Component裝飾器創建元數據。在元數據中,我們指定選擇器的名字,用以標識此組件的元素。 然后,我們導出這個類,以便其它組件可以使用它。
引入文件 import語句 : import {導入的函數} form '路徑';
升級AppComponent的模板,把該組件的selectedHero屬性綁定到HeroDetailComponent組件的hero屬性上。 綁定看起來可能是這樣的:
綁定組件: <my-hero-detail [hero]="selectedHero"></my-hero-detail>
注意,hero是屬性綁定的目標 — 它位於等號 (=) 左邊方括號中。 目標屬性就是需要得到的目標屬性
Angular 希望我們把目標屬性聲明為組件的輸入屬性,否則,Angular 會拒絕綁定,並拋出錯誤。
10.模塊之間的項目引用
@NgModule({ imports: [BrowserModule,FormsModule], declarations:[AppComponent,HeroDetailComponent], bootstrap:[AppComponent] }) export class AppModule { }
declaration這個數組包含了所有創建的並屬於應用模塊組件、管道和指令。
------------------------------------------------------------
小結:創建一個可復用組件的思路(把父組件綁定到子組件中)
1》新建新的裝飾器@Component,在裝飾器中使用自定義標簽selector:'標簽名', 來盛放准備復用的組件
2》在新建的裝飾器@Component的模板telplete中編輯復用模板的view視圖層,這里的數據是自己組件所特有的
3》在組件中通過前面導入的裝飾器向組件中添加注釋的方法省輸入屬性
export class HeroDetailComponent{
@Input()
hero:Hero;
}
4》添加模塊之間的項目引用(在angular中生命該應用所需的指令)
@NgModule({ imports: [BrowserModule,FormsModule], declarations:[AppComponent,HeroDetailComponent], bootstrap:[AppComponent] }) export class AppModule { }
5》在需要復用的地方插入自定義標簽,並綁定相關數據
注入在雙向綁定的時候 屬性綁定目標位於等號的左側,否則angular會拒絕綁定並拋出錯誤
---------------------------------------------------------------
11.服務
引入服務並且在服務中引入服務數據
import { Injectable } from '@angular/core'; import { Hero } from './hero'; import { HEROES } from './mock-heroes'; @Injectable() export class HeroService { getHeroes(): Hero[] { return HEROES; } }
數據使用者並不知道本服務會如何獲取數據。服務可以從任何地方獲取英雄的數據。可以從網絡服務器獲取、從瀏覽器的局部存儲區獲取、可以從模擬的數據源獲取。
這就是從組件中移除數據訪問代碼的美妙之處。 這樣我們可以隨時改變數據訪問的實現方式,而無需對使用英雄的組件作任何改動。
//導入想要的東西,比如服務 導入服務后便可以在代碼中應用 可以new一個HeroService
import {HeroService} from './hero.service';
newnew一個HeroService(服務)的缺點:
1》如果修改了服務代碼,則需要修改每一處使用服務的代碼
2》new的服務實例不能提供緩存數據列表共享
解決辦法:使用providers注入模塊依賴(和angular1中注入模塊意義相同,angular1中的注入模塊能提供constroller之間的相互關聯,暫時可以這么理解),構造函數自己什么也不用做,它在參數中定義了一個私有的heroService屬性,並把它標記為注入HeroService的靶點。
更多注入依賴示例:http://origin.angular.live/docs/ts/latest/guide/dependency-injection.html
constructor(private heroService: HeroService) { }
使用這行代碼錢需要給服務注冊一個提供商(HeroService),來表明(告訴注冊器)服務的來源指向:
providers: [HeroService]
12.ngOnInit生命周期鈎子
更多生命周期鈎子:http://origin.angular.live/docs/ts/latest/guide/lifecycle-hooks.html
ngOnInit接口基本的輪廓
import { OnInit } from '@angular/core'; export class AppComponent implements OnInit { ngOnInit(): void { } }
13.異步服務--承諾 promise
承諾的意思簡單來說就是異步:承諾在有結果的時候給一個回調函數,並通過參數把結果傳遞回來,這個回調promise是ES6語法中的
更過承諾的解釋:http://exploringjs.com/es6/ch_promises.html
服務與承諾 Promise<Hero[]>----TS語法中的泛型,泛型有限制,any無限制
export class HeroService { getHeroes(): Promise<Hero[]> { return Promise.resolve(HEROES); } } export class HeroService { getHeroes(): Promise<Hero[]> { return Promise.resolve(HEROES); } }
使用服務的承諾的時候使用承諾對象的then的方法
//導入數據
getHeroes():void{
//需要獲得的數據在等號的左面,數據來源在等號的右面 服務中使用了Promise,這里的數據來源也需要使用承諾
//把Promise的回調函數的參數傳給承諾對象的箭頭函數(then方法)
this.heroService.getHeroes().then(heroes => this.heroes=heroes);
}
更多箭頭函數:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
模擬慢網速連接:http://origin.angular.live/docs/ts/latest/tutorial/toh-pt4.html#!#slow
服務模塊的小結:
1》創建共享服務類,引入共享的數據 共享數據的構造函數,輸出一個服務,在服務中使用回調函數異步的返回承諾Promise的結果(promise.resolve)
2》使用生命鈎子OnInit在主邏輯激活的時候獲取這個服務(引入OnInit模塊,在輸出的時候添加生命鈎子的的工具--implement OnInit)
3》提供服務的提供商:在裝飾器中添加promises的來源
4》組件從服務中獲取數據:把Promise的回調函數的參數傳給承諾對象的箭頭函數(then方法)
14.路由:angular2的路由是幫你找到另一個組件的;路由是導航的另一個名字。路由器就是從一個視圖導航到另一個視圖的機制。
更多路由和導航的介紹:http://origin.angular.live/docs/ts/latest/guide/router.html
--------------------------------------------------------
新的AppComponent將成為應用的“殼”。 它將在頂部放一些導航鏈接,並且把我們要導航到的頁面放在下面的顯示區中。
這些起始步驟是:
添加支持性的import語句。
創建一個名叫app.component.ts的新文件。
定義一個導出的 AppComponent類。
在類的上方添加@Component元數據裝飾器,裝飾器帶有my-app選擇器。
將下面的項目從HeroesComponent移到AppComponent:
title類屬性
@Component模板中的<h1>標簽,它包含了對title屬性的綁定。
在模板的標題下面添加<my-heroes>標簽,以便我們仍能看到英雄列表。
添加HeroesComponent組件到根模塊的declarations數組中,以便 Angular 能認識<my-heroes>標簽。
添加HeroService到AppModule的providers數組中,因為我們的每一個視圖都需要它。
從HerosComponent的providers數組中移除HeroService,因為它被提到模塊了。
導入AppComponent。
---------------------------------------------------------
Angular 路由器是一個可選的外部 Angular NgModule,名叫RouterModule。 路由器包含了多種服務(RouterModule)、多種指令(RouterOutlet、RouterLink、RouterLinkActive)、 和一套配置(Routes)
路由使用小結:
1》在首頁HTML設置base標簽:在<head>區的頂部添加<base href="/">語句。
更多解釋:http://origin.angular.live/docs/ts/latest/guide/router-deprecated.html#!#base-href
2》配置路由:將路由放入模塊配置@NgModule的入口文件imports數組中
路由告訴路由器,當用戶點擊鏈接或者把 URL 粘貼到瀏覽器地址欄時,應該顯示哪個視圖。
路由定義包括以下部分:更多定義(http://origin.angular.live/docs/ts/latest/guide/router.html)
path: 路由器會用它來匹配瀏覽器地址欄中的地址
component: 導航到此路由時,路由器需要創建的組件
forRoot方法:在應用根部提供配置的路由器。 forRoot方法提供了路由需要的路由服務提供商和指令,並基於當前瀏覽器 URL 初始化導航。
3》路由插座:<router-outlet>,RouterOutlet是RouterModule提供的指令之一。 當我們在應用中導航時,路由器就把激活的組件顯示在<router-outlet>里面。
動態路由器連接和*連接參數數組:http://origin.angular.live/docs/ts/latest/guide/router.html#!#link-parameters-array
4》路由重定向:redirectTo
更多路由重定向:http://origin.angular.live/docs/ts/latest/guide/router.html#!#redirect
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
這只是我自學的筆記,如果有何錯誤歡迎大家指正