angular2 父組件和子組件通過服務(wù)來通訊

原文見我的博客
組件之間的通訊是在angular2的開發(fā)中不可避免的,但是目前官方文檔上介紹的很模糊把跨,不夠詳細故硅,本文將結(jié)合自己的學(xué)習(xí)和實踐來把官網(wǎng)上父組件和子組件通過服務(wù)來通訊的實例程序進行詳細的說明。
父組件和它的子組件共享同一個服務(wù),利用該服務(wù)在家庭內(nèi)部實現(xiàn)雙向通訊渠羞,子組件中的數(shù)據(jù)的更新可以通過服務(wù)通知到其他的子組件。但是該服務(wù)實例的作用域被限制在父組件和其子組件內(nèi)智哀。這個組件子樹之外的組件將無法訪問該服務(wù)或者與它們通訊次询。這樣的一個可以實現(xiàn)父子組件之間的通訊的服務(wù)的寫法和普通的服務(wù)的寫法是不同的是需要在服務(wù)中增加用于通知其他組件數(shù)據(jù)有更改的代碼,這個是通過import { Subject } from ‘rxjs/Subject’來實現(xiàn)的瓷叫。
Subject的介紹

什么是Subject屯吊?在RxJS中,Subject是一類特殊的Observable摹菠,它可以向多個Observer多路推送數(shù)值盒卸。普通的Observable并不具備多路推送的能力(每一個Observer都有自己獨立的執(zhí)行環(huán)境),而Subject可以共享一個執(zhí)行環(huán)境次氨。
我們看看MissionService

import{ Injectable } from'@angular/core';
import{ Subject }    from'rxjs/Subject';
@Injectable()
exportclassMissionService {
//聲明變量 訂閱Observer蔽介,下面這個是一個可以實現(xiàn)組件之間通訊必不可少的
privatemissionAnnouncedSource =newSubject();
privatemissionConfirmedSource =newSubject();
missionAnnounced$ =this.missionAnnouncedSource.asObservable();
missionConfirmed$ =this.missionConfirmedSource.asObservable();
//當組件或者服務(wù)中的數(shù)據(jù)有更改的時候調(diào)用這個方法即可將更改的數(shù)據(jù)推送到其他組件。
announceMission(mission: string) {
this.missionAnnouncedSource.next(mission);
}
confirmMission(astronaut: string) {
this.missionConfirmedSource.next(astronaut);
}
}

調(diào)用Subject對象的next(theValue) 方法后煮寡,Subject會向所有已經(jīng)在其上注冊的Observer多路推送數(shù)據(jù)虹蓄。
現(xiàn)在我們來看看父組件

MissionControlComponent提供服務(wù)的實例,并將其共享給它的子組件(通過providers元數(shù)據(jù)數(shù)組)幸撕,子組件可以通過構(gòu)造函數(shù)將該實例注入到自身薇组。

import{ Component }          from'@angular/core';
import{ MissionService }     from'./mission.service';
@Component({
selector:'mission-control',
template: `
Mission Control
Announce mission
[astronaut]="astronaut">
History

{{event}}
`,
providers: [MissionService]
})
exportclassMissionControlComponent {
astronauts = ['Lovell','Swigert','Haise'];
history: string[] = [];
missions = ['Fly to the moon!',
'Fly to mars!',
'Fly to Vegas!'];
nextMission =0;
constructor(privatemissionService: MissionService) {
missionService.missionConfirmed$.subscribe(
astronaut => {
this.history.push(`${astronaut} confirmed the mission`);
});
}
announce() {
let mission =this.missions[this.nextMission++];
this.missionService.announceMission(mission);
this.history.push(`Mission"${mission}"announced`);
if(this.nextMission >=this.missions.length) {this.nextMission =0; }
}
}

這個例子中服務(wù)的提供者在父組件中提供的,在實際的代碼中可能會報錯坐儿,可以將服務(wù)的提供者放到app.module.ts中律胀。父組件中我們需要關(guān)注一點[astronaut]=”astronaut”,這個是把子組件中的變量和父組件中的變量綁定起來貌矿。這樣astronaut的值在其中一個子組件中有更改的時候服務(wù)通知的時候就可以通知父組件和其他綁定了這個變量的子組件炭菌。
我們在看看子組件:

AstronautComponent也通過自己的構(gòu)造函數(shù)注入該服務(wù)。由于每個AstronautComponent都是MissionControlComponent的子組件逛漫,所以它們獲取到的也是父組件的這個服務(wù)實例黑低。

import{ Component, Input, OnDestroy } from'@angular/core';
import{ MissionService } from'./mission.service';
import{ Subscription }   from'rxjs/Subscription';
@Component({
selector:'my-astronaut',
template: `
{{astronaut}}: **{{mission}}**
(click)="confirm()"
[disabled]="!announced || confirmed">
Confirm
`
})
exportclassAstronautComponentimplementsOnDestroy {
@Input() astronaut: string;
mission ='';
confirmed =false;
announced =false;
subscription: Subscription;
constructor(privatemissionService: MissionService) {
//根據(jù)自己的需要看是否需要
this.subscription = missionService.missionAnnounced$.subscribe(
mission => {
this.mission = mission;
this.announced =true;
this.confirmed =false;
});
}
//這里調(diào)用很關(guān)鍵,必須要有
confirm() {
this.confirmed =true;
this.missionService.confirmMission(this.astronaut);
}
ngOnDestroy() {
// prevent memory leak when component destroyed
this.subscription.unsubscribe();
}
}

在這個子組件中confirm方法調(diào)用了服務(wù)中的confirmMission來通知父組件astronaut的值已經(jīng)更改尽楔。注意投储,通過subscription服務(wù)訂閱任務(wù),并在AstronautComponent被銷毀的時候退訂阔馋。這是一個用于防止內(nèi)存泄漏的保護措施玛荞。實際上,在這個應(yīng)用程序中并沒有這個風(fēng)險呕寝,因為AstronautComponent的生命期和應(yīng)用程序的生命期一樣長勋眯。但在更復(fù)雜的應(yīng)用程序環(huán)境中就不一定了。
總結(jié):angular2父組件和子組件通過服務(wù)來通訊主要有3點
一、在服務(wù)中使用訂閱來想各個組件推動數(shù)據(jù)客蹋;
二塞蹭、在父組件的模板中綁定屬性,父子組件中的構(gòu)造函數(shù)同時使用服務(wù)參數(shù)讶坯;
三番电、在子組件中調(diào)用服務(wù)中的推送來推送數(shù)據(jù)更改,其他子組件可以通過ngOnChanges來檢查更改然后做出相應(yīng)的處理辆琅。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末漱办,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子婉烟,更是在濱河造成了極大的恐慌娩井,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件似袁,死亡現(xiàn)場離奇詭異洞辣,居然都是意外死亡,警方通過查閱死者的電腦和手機昙衅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門扬霜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人绒尊,你說我怎么就攤上這事畜挥∽兄啵” “怎么了婴谱?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長躯泰。 經(jīng)常有香客問我谭羔,道長,這世上最難降的妖魔是什么麦向? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任瘟裸,我火速辦了婚禮,結(jié)果婚禮上诵竭,老公的妹妹穿的比我還像新娘话告。我一直安慰自己,他們只是感情好卵慰,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布沙郭。 她就那樣靜靜地躺著,像睡著了一般裳朋。 火紅的嫁衣襯著肌膚如雪病线。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機與錄音送挑,去河邊找鬼绑莺。 笑死,一個胖子當著我的面吹牛惕耕,可吹牛的內(nèi)容都是我干的纺裁。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼司澎,長吁一口氣:“原來是場噩夢啊……” “哼对扶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起惭缰,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤浪南,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后漱受,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體络凿,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年昂羡,在試婚紗的時候發(fā)現(xiàn)自己被綠了絮记。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡虐先,死狀恐怖怨愤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蛹批,我是刑警寧澤撰洗,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站腐芍,受9級特大地震影響差导,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜猪勇,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一设褐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧泣刹,春花似錦助析、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至襟沮,卻和暖如春锥惋,著一層夾襖步出監(jiān)牢的瞬間昌腰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工膀跌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留遭商,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓捅伤,卻偏偏與公主長得像劫流,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子丛忆,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理祠汇,服務(wù)發(fā)現(xiàn),斷路器熄诡,智...
    卡卡羅2017閱讀 134,651評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,072評論 25 707
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法可很,類相關(guān)的語法,內(nèi)部類的語法凰浮,繼承相關(guān)的語法我抠,異常的語法,線程的語...
    子非魚_t_閱讀 31,622評論 18 399
  • 我見證過谷子的成熟 金燦太陽下的大地 果實已被收割 殘留下地的疤痕 不是痛袜茧,不是荒涼 是孩子成長的痕跡 ——長弓 ...
    郁衡子閱讀 145評論 0 0
  • 閨密青青自嘲自己曾經(jīng)是一條毛毛蟲菜拓,到哪都被忽視的那種。她是我從小的玩伴笛厦,父母離異纳鼎,她跟隨父親長大,所以性格比較陽剛...
    豬囡囡閱讀 301評論 2 1