首頁 web前端 js教程 Angular組件互動步驟詳解

Angular組件互動步驟詳解

May 03, 2018 pm 02:08 PM
angular 步驟 詳解

這次帶給大家Angular組件互動步驟詳解,Angular組件互動步驟詳解的注意事項有哪些,以下就是實戰案例,一起來看一下。

在Angular應用開發中,元件可以說是隨處可見的。本篇文章將介紹幾種常見的元件通訊場景,也就是讓兩個或多個元件之間互動的方法。

依資料的傳遞方向,分為父元件向子元件傳遞、子元件傳遞給父元件、透過服務傳遞三種互動方法。

父元件傳遞給子元件

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

先定義兩個元件,分別為子元件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(屬性值可以為任意資料類型

父元件: 

@Component({
 selector: 'demo-parent',
 template: `
 <demo-child [paramOne]=&#39;paramOneVal&#39; [paramTwo]=&#39;paramTwoVal&#39;></demo-child>
 `
})
export class DemoParentComponent {
 paramOneVal: any = '传递给paramOne的数据';
 paramTwoVal: any = '传递给paramTwo的数据';
}
登入後複製

父元件在其範本中透過選擇器demo-child引用子元件DemoChildComponent,並透過子組件的兩個輸入屬性paramOne和paramTwo向子組件傳遞數據,最後在子組件的模板中就顯示傳遞給paramOne的數據和傳遞給paramTwo的數據這兩行文本。

透過setter 截斷輸入屬性值的變化

在實際應用中,我們往往需要在某個輸入屬性值改變的時候做對應的操作,那麼此時我們需要用到輸入屬性的setter 來截聽輸入屬性值的變化。

我們將子元件DemoChildComponent進行如下改造:

@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賦值給內部私有屬性paramOneVal,達到父元件傳遞資料給子元件的效果。當然,最重要的是,在 setter 裡面你可以做更多的其它操作,程式的彈性就更強了。

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

#透過setter 截斷輸入屬性值的變化的方法只能對單一屬性值變化進行監視,如果需要監視多個、互動式輸入屬性的時候,這種方法就顯得力不從心了。而透過使用OnChanges 生命週期鉤子介面的ngOnChanges() 方法(當元件透過@Input裝飾器明確指定的那些變數的值變化時呼叫)就可以實現同時監視多個輸入屬性值的變化。

在子元件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); // 获取输入属性当前值
   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方法接收的參數changes是以輸入屬性名稱為鍵、值為SimpleChange的對象,SimpleChange物件含有目前輸入屬性是否第一次變更、先前值、目前值等屬性。因此在ngOnChanges方法中透過遍歷changes物件可監視多個輸入屬性值並進行對應的操作。

取得父元件實例

前面介紹的都是子元件透過@Input裝飾器定義輸入屬性,這樣父元件可以透過輸入屬性將資料傳遞給子組件。

當然,我們可以想到一個更主動的方法,那就是取得到父元件實例,然後呼叫父元件的某個屬性或方法來取得所需的資料。考慮到每個元件的實例都會加入註入器的容器裡,因此可透過依賴注入來找到父元件的範例。

子元件取得父元件實例比起父元件取得子元件實例(直接透過範本變數、@ViewChild或@ViewChildren取得)要麻煩一些。

要在子元件中取得父元件的實例,有兩種情況:

已知父元件的類型

這種情況可以直接透過在建構子中註入DemoParentComponent來取得已知類型的父元件引用,程式碼範例如下:

@Component({
 selector: 'demo-child',
 template: `
 <p>{{paramOne}}</p>
 <p>{{paramTwo}}</p>
 `
})
export class DemoChildComponent {
 paramOne: any;
 paramTwo: any;
 constructor(public demoParent: DemoParentComponent) {
  // 通过父组件实例demoParent获取数据
  this.paramOne = demoParent.paramOneVal;
  this.paramTwo = demoParent.paramTwoVal;
 }
}
登入後複製

未知父元件的類型

#

一个组件可能是多个组件的子组件,有时候无法直接知道父组件的类型,在Angular中,可通过类—接口(Class-Interface)的方式来查找,即让父组件通过提供一个与类—接口标识同名的别名来协助查找。

首先创建DemoParent抽象类,它只声明了paramOneVal和paramTwoVal属性,没有实现(赋值),示例代码如下:

export abstract class DemoParent {
 paramOneVal: any;
 paramTwoVal: any;
}
登入後複製

然后在父组件DemoParentComponent的providers元数据中定义一个别名 Provider,用 useExisting 来注入父组件DemoParentComponent的实例,代码示例如下:

@Component({
 selector: 'demo-parent',
 template: `
 <demo-child [paramOne]=&#39;paramOneVal&#39; [paramTwo]=&#39;paramTwoVal&#39;></demo-child>
 `,
 providers: [{provider: DemoParent, useExisting: DemoParentComponent}]
})
export class DemoParentComponent implements DemoParent {
 paramOneVal: any = '传递给paramOne的数据';
 paramTwoVal: any = '传递给paramTwo的数据';
}
登入後複製

然后在子组件中就可通过DemoParent这个标识找到父组件的示例了,示例代码如下:

@Component({
 selector: 'demo-child',
 template: `
 <p>{{paramOne}}</p>
 <p>{{paramTwo}}</p>
 `
})
export class DemoChildComponent {
 paramOne: any;
 paramTwo: any;
 constructor(public demoParent: DemoParent) {
  // 通过父组件实例demoParent获取数据
  this.paramOne = demoParent.paramOneVal;
  this.paramTwo = demoParent.paramTwoVal;
 }
}
登入後複製

子组件向父组件传递

依然先定义两个组件,分别为子组件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); // 打印结果:子组件DemoChildComponent初始化完成!
 }
 onReady(evt: any) {
  console.log(evt); // 打印结果:子组件DemoChildComponent初始化完成!
 }
}
登入後複製

父组件监听子组件的事件

子组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件。父组件绑定到这个事件属性,并在事件发生时作出回应。

在上面定义好的子组件和父组件,我们可以看到:

子组件通过@Output()定义输出属性ready,然后在ngOnInit中利用ready属性的 emits(向上弹射)事件。

父组件在其模板中通过选择器demo-child引用子组件DemoChildComponent,并绑定了一个事件处理器(onReady()),用来响应子组件的事件($event)并打印出数据(onReady($event)中的$event是固定写法,框架(Angular)把事件参数(用 $event 表示)传给事件处理方法)。

父组件与子组件通过本地变量(模板变量)互动

父组件不能使用数据绑定来读取子组件的属性或调用子组件的方法。但可以在父组件模板里,新建一个本地变量来代表子组件,然后利用这个变量来读取子组件的属性和调用子组件的方法。

在上面定义好的子组件和父组件,我们可以看到:

父组件在模板demo-child标签上定义了一个demoChild本地变量,然后在模板中获取子组件的属性:

<p>
 <!-- 获取子组件的属性readyInfo,显示:子组件DemoChildComponent初始化完成! -->
 readyInfo: {{demoChild.readyInfo}}
</p>
登入後複製

父组件调用@ViewChild()

本地变量方法是个简单便利的方法。但是它也有局限性,因为父组件-子组件的连接必须全部在父组件的模板中进行。父组件本身的代码对子组件没有访问权。

如果父组件的类需要读取子组件的属性值或调用子组件的方法,就不能使用本地变量方法。

当父组件类需要这种访问时,可以把子组件作为 ViewChild,注入到父组件里面。

在上面定义好的子组件和父组件,我们可以看到:

父组件在组件类中通过@ViewChild()获取到子组件的实例,然后就可以在模板或者组件类中通过该实例获取子组件的属性:

<p>
 <!-- 通过组件类获取子组件示例,然后获取readyInfo属性,显示:子组件DemoChildComponent初始化完成! -->
 readyInfo: {{demoChildComponent.readyInfo}}
</p>
登入後複製
ngAfterViewInit() {
 console.log(this.demoChildComponent.readyInfo); // 打印结果:子组件DemoChildComponent初始化完成!
}
登入後複製

通过服务传递

Angular的服务可以在模块注入或者组件注入(均通过providers注入)。

在模块中注入的服务在整个Angular应用都可以访问(除惰性加载的模块)。

在组件中注入的服务就只能该组件和其子组件进行访问,这个组件子树之外的组件将无法访问该服务或者与它们通讯。

下面的示例就以在组件中注入的服务来进行父子组件之间的数据传递:

通讯的服务:

@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); // 打印结果:我是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); // 打印结果:我是CallService的info
 }
 
 changeInfo() {
  this.callService.info = '我是被子组件改变的CallService的info';
 }
}
登入後複製

上面的代码中,我们定义了一个CallService服务,在其内定义了info属性,后面将分别在父子组件通过修改这个属性的值达到父子组件互相传递数据的目的。

然后通过DemoParentComponent的providers元数据数组提供CallService服务的实例,并通过构造函数分别注入到父子组件中。

此時,透過父元件改變info按鈕或子元件改變info按鈕在父元件或子元件中改變CallService服務的info屬性值,然後在頁面可看到改變之後對應的info屬性值。

相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!

推薦閱讀:

Node module模組使用詳解(附程式碼)

jQuery Cookie實作切換皮膚效果實作(附程式碼)

以上是Angular組件互動步驟詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何在iPhone中使Google地圖成為預設地圖 如何在iPhone中使Google地圖成為預設地圖 Apr 17, 2024 pm 07:34 PM

iPhone上的預設地圖是Apple專有的地理位置供應商「地圖」。儘管地圖越來越好,但它在美國以外的地區運作不佳。與谷歌地圖相比,它沒有什麼可提供的。在本文中,我們討論了使用Google地圖成為iPhone上的預設地圖的可行性步驟。如何在iPhone中使Google地圖成為預設地圖將Google地圖設定為手機上的預設地圖應用程式比您想像的要容易。請依照以下步驟操作–先決條件步驟–您必須在手機上安裝Gmail。步驟1–開啟AppStore。步驟2–搜尋“Gmail”。步驟3–點選Gmail應用程式旁

升級微信最新版本的步驟(輕鬆掌握微信最新版本的升級方法) 升級微信最新版本的步驟(輕鬆掌握微信最新版本的升級方法) Jun 01, 2024 pm 10:24 PM

不斷推出新版本以提供更好的使用體驗,微信作為中國的社交媒體平台之一。升級微信至最新版本是非常重要的,家人和同事的聯繫、為了保持與朋友、及時了解最新動態。 1.了解最新版本的特性與改進了解最新版本的特性與改進非常重要,在升級微信之前。效能改進和錯誤修復,透過查看微信官方網站或應用程式商店中的更新說明、你可以了解新版本所帶來的各種新功能。 2.檢查目前微信版本我們需要檢查目前手機上已安裝的微信版本、在升級微信之前。點擊,打開微信應用“我”然後選擇,菜單“關於”在這裡你可以看到當前微信的版本號,。 3.打開應

此 Apple ID 尚未在 iTunes Store 中使用:修復 此 Apple ID 尚未在 iTunes Store 中使用:修復 Jun 10, 2024 pm 05:42 PM

使用AppleID登入iTunesStore時,可能會在螢幕上拋出此錯誤提示「此AppleID尚未在iTunesStore中使用」。沒有什麼可擔心的錯誤提示,您可以按照這些解決方案集進行修復。修正1–更改送貨地址此提示出現在iTunesStore中的主要原因是您的AppleID個人資料中沒有正確的地址。步驟1–首先,開啟iPhone上的iPhone設定。步驟2–AppleID應位於所有其他設定的頂部。所以,打開它。步驟3–在那裡,打開“付款和運輸”選項。步驟4–使用面容ID驗證您的存取權限。步驟

Shazam應用程式在iPhone中無法運作:修復 Shazam應用程式在iPhone中無法運作:修復 Jun 08, 2024 pm 12:36 PM

iPhone上的Shazam應用程式有問題? Shazam可協助您透過聆聽歌曲找到歌曲。但是,如果Shazam無法正常工作或無法識別歌曲,則必須手動對其進行故障排除。修復Shazam應用程式不會花費很長時間。因此,無需再浪費時間,請按照以下步驟解決Shazam應用程式的問題。修正1–禁用粗體文字功能iPhone上的粗體文字可能是Shazam無法正常運作的原因。步驟1–您只能從iPhone設定執行此操作。所以,打開它。步驟2–接下來,開啟其中的「顯示和亮度」設定。步驟3–如果您發現啟用了“粗體文本

Win11系統管理員權限取得步驟詳解 Win11系統管理員權限取得步驟詳解 Mar 08, 2024 pm 09:09 PM

Windows11作為微軟最新推出的作業系統,深受廣大用戶喜愛。在使用Windows11的過程中,有時候我們需要取得系統管理員權限,以便進行一些需要權限的操作。接下來將詳細介紹在Windows11中取得系統管理員權限的步驟。第一步,點擊“開始功能表”,在左下角可以看到Windows圖標,點擊該圖標即可開啟“開始功能表”。第二步,在「開始功能表」中尋找並點擊「

iPhone螢幕截圖不起作用:如何修復 iPhone螢幕截圖不起作用:如何修復 May 03, 2024 pm 09:16 PM

螢幕截圖功能在您的iPhone上不起作用嗎?截圖非常簡單,因為您只需同時按住「提高音量」按鈕和「電源」按鈕即可抓取手機螢幕。但是,還有其他方法可以在設備上捕獲幀。修復1–使用輔助觸控使用輔助觸控功能截取螢幕截圖。步驟1–轉到您的手機設定。步驟2–接下來,點選以開啟「輔助功能」設定。步驟3–開啟「觸摸」設定。步驟4–接下來,開啟「輔助觸控」設定。步驟5–打開手機上的「輔助觸控」。步驟6–打開“自訂頂級選單”以存取它。步驟7–現在,您只需將這些功能中的任何一個連結到螢幕擷取即可。因此,點擊那裡的首

iPhone中缺少時鐘應用程式:如何修復 iPhone中缺少時鐘應用程式:如何修復 May 03, 2024 pm 09:19 PM

您的手機中缺少時鐘應用程式嗎?日期和時間仍將顯示在iPhone的狀態列上。但是,如果沒有時鐘應用程序,您將無法使用世界時鐘、碼錶、鬧鐘等多項功能。因此,修復時鐘應用程式的缺失應該是您的待辦事項清單的首位。這些解決方案可以幫助您解決此問題。修復1–放置時鐘應用程式如果您錯誤地從主畫面中刪除了時鐘應用程序,您可以將時鐘應用程式放回原位。步驟1–解鎖iPhone並開始向左側滑動,直到到達「應用程式庫」頁面。步驟2–接下來,在搜尋框中搜尋「時鐘」。步驟3–當您在搜尋結果中看到下方的「時鐘」時,請按住它並

iPhone上的Safari縮小問題:這是修復程序 iPhone上的Safari縮小問題:這是修復程序 Apr 20, 2024 am 08:08 AM

如果您無法控制Safari中的縮放級別,完成工作可能會非常棘手。因此,如果Safari看起來被縮小了,那對您來說可能會有問題。您可以透過以下幾種方法解決Safari中的這個縮小小問題。 1.遊標放大:在Safari選單列中選擇「顯示」>「放大遊標」。這將使遊標在螢幕上更加顯眼,從而更容易控制。 2.移動滑鼠:這聽起來可能很簡單,但有時只需將滑鼠移動到螢幕上的另一個位置,可能會自動恢復正常大小。 3.使用鍵盤快速鍵修復1–重置縮放等級您可以直接從Safari瀏覽器控制縮放等級。步驟1–當您在Safari

See all articles