1. 元數(shù)據(jù):
Angular 需要知道如何把應(yīng)用程序的各個(gè)部分組合到一起齐帚,以及該應(yīng)用需要哪些其它文件和庫疏日。 這些信息被稱為元數(shù)據(jù)(metadata)欲账。
Angular needs to know how the pieces of your application fit together and what other files and libraries the app requires. This information is called metadata.
有些元數(shù)據(jù)位于 @Component
裝飾器中,你會(huì)把它加到組件類上溺职。 另一些關(guān)鍵性的元數(shù)據(jù)位于 @NgModule
裝飾器中岔擂。
最重要的 @NgModule
裝飾器位于頂級(jí)類 AppModule 上。
2. 組件聲明
每個(gè)組件必須聲明浪耘,且只能聲明一次(在一個(gè)ngModule里)乱灵。
- 如果使用@angular/cli創(chuàng)建組件,那么會(huì)自動(dòng)把組件加到 AppModule 中七冲。
- 手動(dòng)創(chuàng)建的組件痛倚,必須手動(dòng)添加聲明。
3. import
所有用到的類型與符號(hào)澜躺,都需要通過import來導(dǎo)入蝉稳。
import { Observable, of } from 'rxjs'; //Observable 和 of 符號(hào)
import { HeroService } from '../hero.service'; //服務(wù)
import { Injectable } from '@angular/core'; //裝飾器
import { FormsModule } from '@angular/forms'; //雙向綁定
import { AppComponent } from './app.component'; //組件
4. 服務(wù)
Why services?
組件不應(yīng)該直接獲取或保存數(shù)據(jù)抒蚜,它們不應(yīng)該了解是否在展示假數(shù)據(jù)。 它們應(yīng)該聚焦于展示數(shù)據(jù)颠区,而把數(shù)據(jù)訪問的職責(zé)委托給某個(gè)服務(wù).
Components shouldn't fetch or save data directly and they certainly shouldn't knowingly present fake data. They should focus on presenting data and delegate data access to a service.
服務(wù)是在多個(gè)“互相不知道”的類之間共享信息的好辦法削锰。
Services are a great way to share information among classes that don't know each other.
在inject一個(gè)服務(wù)到組件之前,需要將這個(gè)服務(wù)注冊(cè)到依賴注入系統(tǒng)毕莱。
我們通過注冊(cè)一個(gè)提供商來完成。
提供商(provider)是什么颅夺?
A provider is something that can create or deliver a service朋截。
看代碼:
@Injectable({
providedIn: 'root' //提供商,root表示根注入器
})
通過Injectable({})裝飾器的注入器providedIn
來注冊(cè)服務(wù)吧黄。
服務(wù)必須具有某種形式的異步函數(shù)簽名部服。因?yàn)闉g覽器不會(huì)在服務(wù)的等待期間停止響應(yīng)。
服務(wù)--可以使用回調(diào)函數(shù)拗慨,可以返回 Promise(承諾)廓八,也可以返回 Observable(可觀察對(duì)象)。
Observable
是 RxJS 庫中的一個(gè)關(guān)鍵類赵抢。
提供商就相當(dāng)于說明書剧蹂,用來指導(dǎo) DI 系統(tǒng)該如何獲取某個(gè)依賴的值。 大多數(shù)情況下烦却,這些依賴就是你要?jiǎng)?chuàng)建和提供的那些服務(wù)宠叼。
A provider is an instruction to the DI system on how to obtain a value for a dependency. Most of the time, these dependencies are services that you create and provide.
5. 模塊
宏觀來講,NgModule 是組織 Angular 應(yīng)用的一種方式其爵,它們通過 NgModule裝飾器中的元數(shù)據(jù)來實(shí)現(xiàn)這一點(diǎn)冒冬。 這些元數(shù)據(jù)可以分成三類:
-
靜態(tài)的:編譯器配置,用于告訴編譯器指令的選擇器并通過選擇器匹配的方式?jīng)Q定要把該指令應(yīng)用到模板中的什么位置摩渺。它是通過 declarations 數(shù)組來配置的简烤。
Static: Compiler configuration which tells the compiler about directive selectors and where in templates the directives should be applied through selector matching. This is configured via the
[declarations](https://www.angular.cn/api/core/NgModule#declarations)
array.
-
運(yùn)行時(shí):通過
providers
數(shù)組提供給注入器的配置。Runtime: Injector configuration via the
providers
array. -
組合/分組:通過 imports 和 exports數(shù)組來把多個(gè) NgModule 放在一起摇幻,并彼此可用横侦。
Composability/Grouping: Bringing NgModules together and making them available via the imports and exportsarrays.
1. @[NgModule](https://www.angular.cn/api/core/NgModule)({
2. // Static, that is compiler configuration
3. declarations: [], // Configure the selectors
4. entryComponents: [], // Generate the host factory
6. // Runtime, or injector configuration
7. providers: [], // Runtime injector configuration
9. // Composability / Grouping
10. imports: [], // composing NgModules together
11. exports: [] // making NgModules available to other parts of the app
12. })
6. 可觀察對(duì)象(Observable)
delete(hero: Hero): void {
this.heroes = this.heroes.filter(h => h !== hero);
this.heroService.deleteHero(hero).subscribe();
}
如果你忘了調(diào)用 subscribe(),本服務(wù)將不會(huì)把這個(gè)刪除請(qǐng)求發(fā)送給服務(wù)器囚企。 作為一條通用的規(guī)則丈咐,Observable 在有人訂閱之前什么都不會(huì)做。
$
是一個(gè)命名慣例龙宏,寫在heroes后面棵逊,用來表明 heroes$
是一個(gè) Observable
,而不是數(shù)組银酗。(如果寫在前面辆影,也是一種命名慣例徒像,用來表示什么呢?小伙伴們可以在留言區(qū)把答案寫上)蛙讥。
*[ngFor]
不能直接使用 Observable
锯蛀。 不過,它后面還有一個(gè)管道字符(|
)次慢,后面緊跟著一個(gè) [async]
旁涤,它表示 Angular 的 [AsyncPipe]
。
[AsyncPipe]
會(huì)自動(dòng)訂閱到 Observable
迫像,這樣你就不用再在組件類中訂閱了劈愚。
可觀察對(duì)象是聲明式的 —— 也就是說,雖然你定義了一個(gè)用于發(fā)布值的函數(shù)闻妓,但是在有消費(fèi)者訂閱它之前菌羽,這個(gè)函數(shù)并不會(huì)實(shí)際執(zhí)行。 訂閱之后由缆,當(dāng)這個(gè)函數(shù)執(zhí)行完或取消訂閱時(shí)注祖,訂閱者就會(huì)收到通知。
Observables are declarative—that is, you define a function for publishing values, but it is not executed until a consumer subscribes to it. The subscribed consumer then receives notifications until the function completes, or until they unsubscribe.
Observables 同 Observer 之間的訂閱發(fā)布關(guān)系如下:
訂閱: Observer 通過 Observable 提供的 subscribe() 方法訂閱 Observable均唉。
發(fā)布:Observable 通過回調(diào) next 方法向 Observer 發(fā)布事件是晨。
Observables 的訂閱類似于函數(shù)的調(diào)用。執(zhí)行時(shí)同步的浸卦。
Observables 傳遞值時(shí)署鸡,可以是同步的,也可以是異步的限嫌。
Observables 與函數(shù)的區(qū)別是:Observable 可以隨著時(shí)間的推移“返回”多個(gè)值靴庆。
結(jié)論:
函數(shù)是 :同步的給我一個(gè)值。
Observables 是 隨著時(shí)間怒医,給我任意多個(gè)值炉抒,無論是同步還是異步的。
7. 路由(router)
每個(gè)路由模塊都會(huì)根據(jù)導(dǎo)入的順序把自己的路由配置追加進(jìn)去稚叹。
路由配置的順序很重要焰薄。 路由器會(huì)接受第一個(gè)匹配上導(dǎo)航所要求的路徑的那個(gè)路由。
ActivatedRouter
有兩個(gè)舊式屬性仍然是有效的扒袖,但它們不如其替代品那樣強(qiáng)力塞茅,建議不再用它們,它們還將在未來的 Angular 版本中廢棄季率。
params
—— 一個(gè) Observable
對(duì)象野瘦,其中包含當(dāng)前路由的必要參數(shù)和可選參數(shù)。請(qǐng)改用 paramMap
。
queryParams
—— 一個(gè) Observable
對(duì)象鞭光,其中包含對(duì)所有路由都有效的查詢參數(shù)吏廉。請(qǐng)改用 queryParamMap
。
8. Operators (操作符)
操作符是 Observable 類型上的方法惰许,比如 .map(...)席覆、.filter(...)、.merge(...)汹买,等等佩伤。當(dāng)操作符被調(diào)用時(shí),它們不會(huì)改變已經(jīng)存在的 Observable 實(shí)例晦毙。相反畦戒,它們返回一個(gè)新的 Observable ,它的 subscription 邏輯基于第一個(gè) Observable 结序。
操作符是函數(shù),它基于當(dāng)前的 Observable 創(chuàng)建一個(gè)新的 Observable纵潦。這是一個(gè)無副作用的操作:前面的 Observable 保持不變徐鹤。
(實(shí)例操作符)
操作符本質(zhì)上是一個(gè)純函數(shù) (pure function),它接收一個(gè) Observable 作為輸入邀层,并生成一個(gè)新的 Observable 作為輸出返敬。訂閱輸出 Observable 同樣會(huì)訂閱輸入 Observable 。
操作符 圖形可以參考此網(wǎng)站:
http://rxmarbles.com/
9. $event
$event 對(duì)象的屬性取決于 DOM 事件的類型寥院。所有標(biāo)準(zhǔn) DOM 事件對(duì)象都有一個(gè) target
屬性劲赠, 引用觸發(fā)該事件的元素。
如果是<input>觸發(fā)的事件秸谢,則通過$event.target.value返回的是輸入的文本凛澎。