欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Angular 組件之間的交互的示例代碼

 更新時(shí)間:2018年03月24日 17:20:27   作者:laixiangran  
這篇文章主要介紹了Angular 組件之間的交互的示例代碼,根據(jù)數(shù)據(jù)的傳遞方向,分為父組件向子組件傳遞、子組件向父組件傳遞及通過服務(wù)傳遞三種交互方法。非常具有實(shí)用價(jià)值,需要的朋友可以參考下

在Angular應(yīng)用開發(fā)中,組件可以說是隨處可見的。本篇文章將介紹幾種常見的組件通訊場(chǎng)景,也就是讓兩個(gè)或多個(gè)組件之間交互的方法。

根據(jù)數(shù)據(jù)的傳遞方向,分為父組件向子組件傳遞、子組件向父組件傳遞及通過服務(wù)傳遞三種交互方法。

父組件向子組件傳遞

子組件通過@Input裝飾器定義輸入屬性,然后父組件在引用子組件的時(shí)候通過這些輸入屬性向子組件傳遞數(shù)據(jù),子組件可通過setter或ngOnChanges()來截聽輸入屬性值的變化。

先定義兩個(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
} 

子組件通過@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ù)';
} 

父組件在其模板中通過選擇器demo-child引用子組件DemoChildComponent,并通過子組件的兩個(gè)輸入屬性paramOne和paramTwo向子組件傳遞數(shù)據(jù),最后在子組件的模板中就顯示傳遞給paramOne的數(shù)據(jù)和傳遞給paramTwo的數(shù)據(jù)這兩行文本。

通過 setter 截聽輸入屬性值的變化

在實(shí)際應(yīng)用中,我們往往需要在某個(gè)輸入屬性值發(fā)生變化的時(shí)候做相應(yīng)的操作,那么此時(shí)我們需要用到輸入屬性的 setter 來截聽輸入屬性值的變化。

我們將子組件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
} 

在上面的代碼中,我們可以看到通過paramOne屬性的 setter 將攔截到的值val賦值給內(nèi)部私有屬性paramOneVal,達(dá)到父組件傳遞數(shù)據(jù)給子組件的效果。當(dāng)然,最重要的是,在 setter 里面你可以做更多的其它操作,程序的靈活性就更強(qiáng)了。

通過ngOnChanges()來截聽輸入屬性值的變化

通過 setter 截聽輸入屬性值的變化的方法只能對(duì)單個(gè)屬性值變化進(jìn)行監(jiān)視,如果需要監(jiān)視多個(gè)、交互式輸入屬性的時(shí)候,這種方法就顯得力不從心了。而通過使用 OnChanges 生命周期鉤子接口的 ngOnChanges() 方法(當(dāng)組件通過@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方法中通過遍歷changes對(duì)象可監(jiān)視多個(gè)輸入屬性值并進(jìn)行相應(yīng)的操作。

獲取父組件實(shí)例

前面介紹的都是子組件通過@Input裝飾器定義輸入屬性,這樣父組件可通過輸入屬性將數(shù)據(jù)傳遞給子組件。

當(dāng)然,我們可以想到一種更主動(dòng)的方法,那就是獲取到父組件實(shí)例,然后調(diào)用父組件的某個(gè)屬性或方法來獲取需要的數(shù)據(jù)??紤]到每個(gè)組件的實(shí)例都會(huì)添加到注入器的容器里,因此可通過依賴注入來找到父組件的示例。

子組件獲取父組件實(shí)例相比于父組件獲取子組件實(shí)例(直接通過模板變量、@ViewChild或@ViewChildren獲?。┮闊┮恍?。

要在子組件中獲取父組件的實(shí)例,有兩種情況:

已知父組件的類型

這種情況可以直接通過在構(gòu)造函數(shù)中注入DemoParentComponent來獲取已知類型的父組件引用,代碼示例如下:

@Component({
 selector: 'demo-child',
 template: `
 <p>{{paramOne}}</p>
 <p>{{paramTwo}}</p>
 `
})
export class DemoChildComponent {
 paramOne: any;
 paramTwo: any;

 constructor(public demoParent: DemoParentComponent) {

  // 通過父組件實(shí)例demoParent獲取數(shù)據(jù)
  this.paramOne = demoParent.paramOneVal;
  this.paramTwo = demoParent.paramTwoVal;
 }
}

未知父組件的類型

一個(gè)組件可能是多個(gè)組件的子組件,有時(shí)候無法直接知道父組件的類型,在Angular中,可通過類—接口(Class-Interface)的方式來查找,即讓父組件通過提供一個(gè)與類—接口標(biāo)識(shí)同名的別名來協(xié)助查找。

首先創(chuàng)建DemoParent抽象類,它只聲明了paramOneVal和paramTwoVal屬性,沒有實(shí)現(xiàn)(賦值),示例代碼如下:

export abstract class DemoParent {
 paramOneVal: any;
 paramTwoVal: any;
} 

然后在父組件DemoParentComponent的providers元數(shù)據(jù)中定義一個(gè)別名 Provider,用 useExisting 來注入父組件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ù)';
} 

然后在子組件中就可通過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) {

  // 通過父組件實(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>
  <!-- 通過本地變量獲取readyInfo屬性,顯示:子組件DemoChildComponent初始化完成! -->
  readyInfo: {{demoChild.readyInfo}}
 </p>
 <p>
  <!-- 通過組件類獲取子組件示例,然后獲取readyInfo屬性,顯示:子組件DemoChildComponent初始化完成! -->
  readyInfo: {{demoChildComponent.readyInfo}}
 </p>
 `
})
export class DemoParentComponent implements AfterViewInit {
 // @ViewChild('demoChild') demoChildComponent: DemoChildComponent; // 通過模板別名獲取
 @ViewChild(DemoChildComponent) demoChildComponent: DemoChildComponent; // 通過組件類型獲取
 
 ngAfterViewInit() {
  console.log(this.demoChildComponent.readyInfo); // 打印結(jié)果:子組件DemoChildComponent初始化完成!
 }

 onReady(evt: any) {
  console.log(evt); // 打印結(jié)果:子組件DemoChildComponent初始化完成!
 }
} 

父組件監(jiān)聽子組件的事件

子組件暴露一個(gè) EventEmitter 屬性,當(dāng)事件發(fā)生時(shí),子組件利用該屬性 emits(向上彈射)事件。父組件綁定到這個(gè)事件屬性,并在事件發(fā)生時(shí)作出回應(yīng)。

在上面定義好的子組件和父組件,我們可以看到:

子組件通過@Output()定義輸出屬性ready,然后在ngOnInit中利用ready屬性的 emits(向上彈射)事件。

父組件在其模板中通過選擇器demo-child引用子組件DemoChildComponent,并綁定了一個(gè)事件處理器(onReady()),用來響應(yīng)子組件的事件($event)并打印出數(shù)據(jù)(onReady($event)中的$event是固定寫法,框架(Angular)把事件參數(shù)(用 $event 表示)傳給事件處理方法)。

父組件與子組件通過本地變量(模板變量)互動(dòng)

父組件不能使用數(shù)據(jù)綁定來讀取子組件的屬性或調(diào)用子組件的方法。但可以在父組件模板里,新建一個(gè)本地變量來代表子組件,然后利用這個(gè)變量來讀取子組件的屬性和調(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ì)子組件沒有訪問權(quán)。

如果父組件的類需要讀取子組件的屬性值或調(diào)用子組件的方法,就不能使用本地變量方法。

當(dāng)父組件類需要這種訪問時(shí),可以把子組件作為 ViewChild,注入到父組件里面。

在上面定義好的子組件和父組件,我們可以看到:

父組件在組件類中通過@ViewChild()獲取到子組件的實(shí)例,然后就可以在模板或者組件類中通過該實(shí)例獲取子組件的屬性:

<p>
 <!-- 通過組件類獲取子組件示例,然后獲取readyInfo屬性,顯示:子組件DemoChildComponent初始化完成! -->
 readyInfo: {{demoChildComponent.readyInfo}}
</p> 
ngAfterViewInit() {
 console.log(this.demoChildComponent.readyInfo); // 打印結(jié)果:子組件DemoChildComponent初始化完成!
} 

通過服務(wù)傳遞

Angular的服務(wù)可以在模塊注入或者組件注入(均通過providers注入)。

在模塊中注入的服務(wù)在整個(gè)Angular應(yīng)用都可以訪問(除惰性加載的模塊)。

在組件中注入的服務(wù)就只能該組件和其子組件進(jìn)行訪問,這個(gè)組件子樹之外的組件將無法訪問該服務(wù)或者與它們通訊。

下面的示例就以在組件中注入的服務(wù)來進(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屬性,后面將分別在父子組件通過修改這個(gè)屬性的值達(dá)到父子組件互相傳遞數(shù)據(jù)的目的。

然后通過DemoParentComponent的providers元數(shù)據(jù)數(shù)組提供CallService服務(wù)的實(shí)例,并通過構(gòu)造函數(shù)分別注入到父子組件中。

此時(shí),通過父組件改變info按鈕或子組件改變info按鈕在父組件或子組件中改變CallService服務(wù)的info屬性值,然后在頁(yè)面可看到改變之后對(duì)應(yīng)的info屬性值。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • angular2中router路由跳轉(zhuǎn)navigate的使用與刷新頁(yè)面問題詳解

    angular2中router路由跳轉(zhuǎn)navigate的使用與刷新頁(yè)面問題詳解

    這篇文章主要給大家介紹了angular2中router路由跳轉(zhuǎn)navigate的使用與刷新頁(yè)面問題的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。
    2017-05-05
  • AngularJS 多指令Scope問題的解決

    AngularJS 多指令Scope問題的解決

    本文介紹了AngularJS 多指令Scope問題的解決,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-10-10
  • Angular8 簡(jiǎn)單表單驗(yàn)證的實(shí)現(xiàn)示例

    Angular8 簡(jiǎn)單表單驗(yàn)證的實(shí)現(xiàn)示例

    這篇文章主要介紹了Angular8 簡(jiǎn)單表單驗(yàn)證的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • 使用AngularJS中的SCE來防止XSS攻擊的方法

    使用AngularJS中的SCE來防止XSS攻擊的方法

    這篇文章主要介紹了使用AngularJS中的SCE來防止XSS攻擊的方法,依靠合理地轉(zhuǎn)碼為HTML來預(yù)防跨站腳本漏洞共計(jì),需要的朋友可以參考下
    2015-06-06
  • angularjs使用div模擬textarea文本框的方法

    angularjs使用div模擬textarea文本框的方法

    今天小編就為大家分享一篇angularjs使用div模擬textarea文本框的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • 詳解Angular動(dòng)態(tài)組件

    詳解Angular動(dòng)態(tài)組件

    本文主要介紹了Angular動(dòng)態(tài)組件,對(duì)此感興趣的同學(xué),可以親自實(shí)驗(yàn)一下。
    2021-05-05
  • 詳解Ubuntu安裝angular-cli遇到的坑

    詳解Ubuntu安裝angular-cli遇到的坑

    這篇文章主要介紹了詳解Ubuntu安裝angular-cli遇到的坑,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-09-09
  • Angular2表單自定義驗(yàn)證器的實(shí)現(xiàn)

    Angular2表單自定義驗(yàn)證器的實(shí)現(xiàn)

    本文給大家介紹angular2表單自定義驗(yàn)證器的實(shí)現(xiàn),本文給大家介紹的非常詳細(xì),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧
    2016-10-10
  • AngularJS service之select下拉菜單效果

    AngularJS service之select下拉菜單效果

    這篇文章主要為大家詳細(xì)介紹了AngularJS service之select下拉菜單效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Angular4學(xué)習(xí)教程之DOM屬性綁定詳解

    Angular4學(xué)習(xí)教程之DOM屬性綁定詳解

    這篇文章主要給大家介紹了關(guān)于Angular4學(xué)習(xí)教程之DOM屬性綁定的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01

最新評(píng)論