這篇文章給大家介紹怎么在Angular中怎么實(shí)現(xiàn)組件之間的交互,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
郁南ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來(lái)市場(chǎng)廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!父組件向子組件傳遞
子組件通過(guò)@Input裝飾器定義輸入屬性,然后父組件在引用子組件的時(shí)候通過(guò)這些輸入屬性向子組件傳遞數(shù)據(jù),子組件可通過(guò)setter或ngOnChanges()來(lái)截聽(tīng)輸入屬性值的變化。
先定義兩個(gè)組件,分別為子組件DemoChildComponent和父組件DemoParentComponent.
子組件:
@Component({ selector: 'demo-child', template: ` <p>{{paramOne}}</p> <p>{{paramTwo}}</p> ` }) export class DemoChildComponent { @Input() paramOne: any; // 輸入屬性1 @Input() paramTwo: any; // 輸入屬性2 }
子組件通過(guò)@Input()定義輸入屬性paramOne和paramTwo(屬性值可以為任意數(shù)據(jù)類型)
父組件:
@Component({ selector: 'demo-parent', template: ` <demo-child [paramOne]='paramOneVal' [paramTwo]='paramTwoVal'></demo-child> ` }) export class DemoParentComponent { paramOneVal: any = '傳遞給paramOne的數(shù)據(jù)'; paramTwoVal: any = '傳遞給paramTwo的數(shù)據(jù)'; }
父組件在其模板中通過(guò)選擇器demo-child引用子組件DemoChildComponent,并通過(guò)子組件的兩個(gè)輸入屬性paramOne和paramTwo向子組件傳遞數(shù)據(jù),最后在子組件的模板中就顯示傳遞給paramOne的數(shù)據(jù)和傳遞給paramTwo的數(shù)據(jù)這兩行文本。
通過(guò) setter 截聽(tīng)輸入屬性值的變化
在實(shí)際應(yīng)用中,我們往往需要在某個(gè)輸入屬性值發(fā)生變化的時(shí)候做相應(yīng)的操作,那么此時(shí)我們需要用到輸入屬性的 setter 來(lái)截聽(tīng)輸入屬性值的變化。
我們將子組件DemoChildComponent進(jìn)行如下改造:
@Component({ selector: 'demo-child', template: ` <p>{{paramOneVal}}</p> <p>{{paramTwo}}</p> ` }) export class DemoChildComponent { private paramOneVal: any; @Input() set paramOne (val: any) { // 輸入屬性1 this.paramOneVal = val; // dosomething }; get paramOne () { return this.paramOneVal; }; @Input() paramTwo: any; // 輸入屬性2 }
在上面的代碼中,我們可以看到通過(guò)paramOne屬性的 setter 將攔截到的值val賦值給內(nèi)部私有屬性paramOneVal,達(dá)到父組件傳遞數(shù)據(jù)給子組件的效果。當(dāng)然,最重要的是,在 setter 里面你可以做更多的其它操作,程序的靈活性就更強(qiáng)了。
通過(guò)ngOnChanges()來(lái)截聽(tīng)輸入屬性值的變化
通過(guò) setter 截聽(tīng)輸入屬性值的變化的方法只能對(duì)單個(gè)屬性值變化進(jìn)行監(jiān)視,如果需要監(jiān)視多個(gè)、交互式輸入屬性的時(shí)候,這種方法就顯得力不從心了。而通過(guò)使用 OnChanges 生命周期鉤子接口的 ngOnChanges() 方法(當(dāng)組件通過(guò)@Input裝飾器顯式指定的那些變量的值變化時(shí)調(diào)用)就可以實(shí)現(xiàn)同時(shí)監(jiān)視多個(gè)輸入屬性值的變化。
在子組件DemoChildComponent新增ngOnChanges:
@Component({ selector: 'demo-child', template: ` <p>{{paramOneVal}}</p> <p>{{paramTwo}}</p> ` }) export class DemoChildComponent implements OnChanges { private paramOneVal: any; @Input() set paramOne (val: any) { // 輸入屬性1 this.paramOneVal = val; // dosomething }; get paramOne () { return this.paramOneVal; }; @Input() paramTwo: any; // 輸入屬性2 ngOnChanges(changes: {[propKey: string]: SimpleChange}) { for (let propName in changes) { // 遍歷changes let changedProp = changes[propName]; // propName是輸入屬性的變量名稱 let to = JSON.stringify(changedProp.currentValue); // 獲取輸入屬性當(dāng)前值 if (changedProp.isFirstChange()) { // 判斷輸入屬性是否首次變化 console.log(`Initial value of ${propName} set to ${to}`); } else { let from = JSON.stringify(changedProp.previousValue); // 獲取輸入屬性先前值 console.log(`${propName} changed from ${from} to ${to}`); } } } }
新增的ngOnChanges方法接收的參數(shù)changes是以輸入屬性名稱為鍵、值為SimpleChange的對(duì)象,SimpleChange對(duì)象含有當(dāng)前輸入屬性是否第一次變化、先前值、當(dāng)前值等屬性。因此在ngOnChanges方法中通過(guò)遍歷changes對(duì)象可監(jiān)視多個(gè)輸入屬性值并進(jìn)行相應(yīng)的操作。
獲取父組件實(shí)例
前面介紹的都是子組件通過(guò)@Input裝飾器定義輸入屬性,這樣父組件可通過(guò)輸入屬性將數(shù)據(jù)傳遞給子組件。
當(dāng)然,我們可以想到一種更主動(dòng)的方法,那就是獲取到父組件實(shí)例,然后調(diào)用父組件的某個(gè)屬性或方法來(lái)獲取需要的數(shù)據(jù)??紤]到每個(gè)組件的實(shí)例都會(huì)添加到注入器的容器里,因此可通過(guò)依賴注入來(lái)找到父組件的示例。
子組件獲取父組件實(shí)例相比于父組件獲取子組件實(shí)例(直接通過(guò)模板變量、@ViewChild或@ViewChildren獲取)要麻煩一些。
要在子組件中獲取父組件的實(shí)例,有兩種情況:
已知父組件的類型
這種情況可以直接通過(guò)在構(gòu)造函數(shù)中注入DemoParentComponent來(lái)獲取已知類型的父組件引用,代碼示例如下:
@Component({ selector: 'demo-child', template: ` <p>{{paramOne}}</p> <p>{{paramTwo}}</p> ` }) export class DemoChildComponent { paramOne: any; paramTwo: any; constructor(public demoParent: DemoParentComponent) { // 通過(guò)父組件實(shí)例demoParent獲取數(shù)據(jù) this.paramOne = demoParent.paramOneVal; this.paramTwo = demoParent.paramTwoVal; } }
未知父組件的類型
一個(gè)組件可能是多個(gè)組件的子組件,有時(shí)候無(wú)法直接知道父組件的類型,在Angular中,可通過(guò)類—接口(Class-Interface)的方式來(lái)查找,即讓父組件通過(guò)提供一個(gè)與類—接口標(biāo)識(shí)同名的別名來(lái)協(xié)助查找。
首先創(chuàng)建DemoParent抽象類,它只聲明了paramOneVal和paramTwoVal屬性,沒(méi)有實(shí)現(xiàn)(賦值),示例代碼如下:
export abstract class DemoParent { paramOneVal: any; paramTwoVal: any; }
然后在父組件DemoParentComponent的providers元數(shù)據(jù)中定義一個(gè)別名 Provider,用 useExisting 來(lái)注入父組件DemoParentComponent的實(shí)例,代碼示例如下:
@Component({ selector: 'demo-parent', template: ` <demo-child [paramOne]='paramOneVal' [paramTwo]='paramTwoVal'></demo-child> `, providers: [{provider: DemoParent, useExisting: DemoParentComponent}] }) export class DemoParentComponent implements DemoParent { paramOneVal: any = '傳遞給paramOne的數(shù)據(jù)'; paramTwoVal: any = '傳遞給paramTwo的數(shù)據(jù)'; }
然后在子組件中就可通過(guò)DemoParent這個(gè)標(biāo)識(shí)找到父組件的示例了,示例代碼如下:
@Component({ selector: 'demo-child', template: ` <p>{{paramOne}}</p> <p>{{paramTwo}}</p> ` }) export class DemoChildComponent { paramOne: any; paramTwo: any; constructor(public demoParent: DemoParent) { // 通過(guò)父組件實(shí)例demoParent獲取數(shù)據(jù) this.paramOne = demoParent.paramOneVal; this.paramTwo = demoParent.paramTwoVal; } }
子組件向父組件傳遞
依然先定義兩個(gè)組件,分別為子組件DemoChildComponent和父組件DemoParentComponent.
子組件:
@Component({ selector: 'demo-child', template: ` <p>子組件DemoChildComponent</p> ` }) export class DemoChildComponent implements OnInit { readyInfo: string = '子組件DemoChildComponent初始化完成!'; @Output() ready: EventEmitter = new EventEmitter<any>(); // 輸出屬性 ngOnInit() { this.ready.emit(this.readyInfo); } }
父組件:
@Component({ selector: 'demo-parent', template: ` <demo-child (ready)="onReady($event)" #demoChild></demo-child> <p> <!-- 通過(guò)本地變量獲取readyInfo屬性,顯示:子組件DemoChildComponent初始化完成! --> readyInfo: {{demoChild.readyInfo}} </p> <p> <!-- 通過(guò)組件類獲取子組件示例,然后獲取readyInfo屬性,顯示:子組件DemoChildComponent初始化完成! --> readyInfo: {{demoChildComponent.readyInfo}} </p> ` }) export class DemoParentComponent implements AfterViewInit { // @ViewChild('demoChild') demoChildComponent: DemoChildComponent; // 通過(guò)模板別名獲取 @ViewChild(DemoChildComponent) demoChildComponent: DemoChildComponent; // 通過(guò)組件類型獲取 ngAfterViewInit() { console.log(this.demoChildComponent.readyInfo); // 打印結(jié)果:子組件DemoChildComponent初始化完成! } onReady(evt: any) { console.log(evt); // 打印結(jié)果:子組件DemoChildComponent初始化完成! } }
父組件監(jiān)聽(tīng)子組件的事件
子組件暴露一個(gè) EventEmitter 屬性,當(dāng)事件發(fā)生時(shí),子組件利用該屬性 emits(向上彈射)事件。父組件綁定到這個(gè)事件屬性,并在事件發(fā)生時(shí)作出回應(yīng)。
在上面定義好的子組件和父組件,我們可以看到:
子組件通過(guò)@Output()定義輸出屬性ready,然后在ngOnInit中利用ready屬性的 emits(向上彈射)事件。
父組件在其模板中通過(guò)選擇器demo-child引用子組件DemoChildComponent,并綁定了一個(gè)事件處理器(onReady()),用來(lái)響應(yīng)子組件的事件($event)并打印出數(shù)據(jù)(onReady($event)中的$event是固定寫法,框架(Angular)把事件參數(shù)(用 $event 表示)傳給事件處理方法)。
父組件與子組件通過(guò)本地變量(模板變量)互動(dòng)
父組件不能使用數(shù)據(jù)綁定來(lái)讀取子組件的屬性或調(diào)用子組件的方法。但可以在父組件模板里,新建一個(gè)本地變量來(lái)代表子組件,然后利用這個(gè)變量來(lái)讀取子組件的屬性和調(diào)用子組件的方法。
在上面定義好的子組件和父組件,我們可以看到:
父組件在模板demo-child標(biāo)簽上定義了一個(gè)demoChild本地變量,然后在模板中獲取子組件的屬性:
<p> <!-- 獲取子組件的屬性readyInfo,顯示:子組件DemoChildComponent初始化完成! --> readyInfo: {{demoChild.readyInfo}} </p>
父組件調(diào)用@ViewChild()
本地變量方法是個(gè)簡(jiǎn)單便利的方法。但是它也有局限性,因?yàn)楦附M件-子組件的連接必須全部在父組件的模板中進(jìn)行。父組件本身的代碼對(duì)子組件沒(méi)有訪問(wèn)權(quán)。
如果父組件的類需要讀取子組件的屬性值或調(diào)用子組件的方法,就不能使用本地變量方法。
當(dāng)父組件類需要這種訪問(wèn)時(shí),可以把子組件作為 ViewChild,注入到父組件里面。
在上面定義好的子組件和父組件,我們可以看到:
父組件在組件類中通過(guò)@ViewChild()獲取到子組件的實(shí)例,然后就可以在模板或者組件類中通過(guò)該實(shí)例獲取子組件的屬性:
<p> <!-- 通過(guò)組件類獲取子組件示例,然后獲取readyInfo屬性,顯示:子組件DemoChildComponent初始化完成! --> readyInfo: {{demoChildComponent.readyInfo}} </p>
ngAfterViewInit() { console.log(this.demoChildComponent.readyInfo); // 打印結(jié)果:子組件DemoChildComponent初始化完成! }
通過(guò)服務(wù)傳遞
Angular的服務(wù)可以在模塊注入或者組件注入(均通過(guò)providers注入)。
在模塊中注入的服務(wù)在整個(gè)Angular應(yīng)用都可以訪問(wèn)(除惰性加載的模塊)。
在組件中注入的服務(wù)就只能該組件和其子組件進(jìn)行訪問(wèn),這個(gè)組件子樹之外的組件將無(wú)法訪問(wèn)該服務(wù)或者與它們通訊。
下面的示例就以在組件中注入的服務(wù)來(lái)進(jìn)行父子組件之間的數(shù)據(jù)傳遞:
通訊的服務(wù):
@Injectable() export class CallService { info: string = '我是CallService的info'; }
父組件:
@Component({ selector: 'demo-parent', template: ` <demo-child></demo-child> <button (click)="changeInfo()">父組件改變info</button> <p> <!-- 顯示:我是CallService的info --> {{callService.info}} </p> `, providers: [CallService] }) export class DemoParentComponent { constructor(public callService: CallService) { console.log(callService.info); // 打印結(jié)果:我是CallService的info } changeInfo() { this.callService.info = '我是被父組件改變的CallService的info'; } }
子組件:
@Component({ selector: 'demo-child', template: ` <button (click)="changeInfo()">子組件改變info</button> ` }) export class DemoChildComponent { constructor(public callService: CallService) { console.log(callService.info); // 打印結(jié)果:我是CallService的info } changeInfo() { this.callService.info = '我是被子組件改變的CallService的info'; } }
上面的代碼中,我們定義了一個(gè)CallService服務(wù),在其內(nèi)定義了info屬性,后面將分別在父子組件通過(guò)修改這個(gè)屬性的值達(dá)到父子組件互相傳遞數(shù)據(jù)的目的。
然后通過(guò)DemoParentComponent的providers元數(shù)據(jù)數(shù)組提供CallService服務(wù)的實(shí)例,并通過(guò)構(gòu)造函數(shù)分別注入到父子組件中。
關(guān)于怎么在Angular中怎么實(shí)現(xiàn)組件之間的交互就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
當(dāng)前名稱:怎么在Angular中怎么實(shí)現(xiàn)組件之間的交互-創(chuàng)新互聯(lián)
URL網(wǎng)址:http://redsoil1982.com.cn/article10/dopcgo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、動(dòng)態(tài)網(wǎng)站、云服務(wù)器、微信小程序、域名注冊(cè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容